Changeset 172665 in webkit


Ignore:
Timestamp:
Aug 15, 2014 6:45:40 PM (10 years ago)
Author:
msaboff@apple.com
Message:

Change callToJavaScript and callToNativeFunction so their callFrames match the native calling conventions
https://bugs.webkit.org/show_bug.cgi?id=131578

Reviewed by Geoffrey Garen.

Renamed callToJavaScript and callToNativeFunction to vmEntryToJavaScript and vmEntryToNative,
respectively. Eliminated the sentinel frame and replaced it with the structure VMEntryRecord
that appears in the "locals" area of a VM entry stack frame. Changed the order that
vmEntryToJavaScript and vmEntryToNative creates their stack frames to be native calling
convention compliant. That is to save prior frame pointer, save callee save registers, then
allocate and populate the VMEntryRecord, and finally allocate a CallFrame for the JS function
that vmEntryToJavaScript will invoke. The top most vm entry frame pointer is saved in
VM::topVMEntryFrame. The vmEntry functions save prior contents of VM::topVMEntryFrame
along with the VM and VM::topCallFrame in the VMEntryRecord it places on the stack. Starting
at VM::topCallFrame, the stack can be walked using these VMEntryRecords.

Arbitrary stack unwinding is now handled either iteratively by loading VM::topVMEntryFrame
into a local variable and using CallFrame::callerFrame(VMEntryFrame*&) or by using StackVisitor.
Given that the stack is effectively a singly linked list, general stack unwinding needs to use
one of these two methods.

Addition of VMEntryRecord.h

  • bytecode/BytecodeList.json:

Renaming of llint helper opcodes due to renaming callToJavaScript and callToNativeFunction.

  • debugger/Debugger.cpp:

(JSC::Debugger::stepOutOfFunction):
(JSC::Debugger::returnEvent):
(JSC::Debugger::didExecuteProgram):

  • jsc.cpp:

(functionDumpCallFrame):

  • jit/JITOperations.cpp:

Changed unwinding to use CallFrame::callerFrame(VMEntryFrame*&).

  • bytecode/CodeBlock.cpp:

(JSC::RecursionCheckFunctor::RecursionCheckFunctor):
(JSC::RecursionCheckFunctor::operator()):
(JSC::RecursionCheckFunctor::didRecurse):
(JSC::CodeBlock::noticeIncomingCall):

  • debugger/DebuggerCallFrame.cpp:

(JSC::FindCallerMidStackFunctor::FindCallerMidStackFunctor):
(JSC::FindCallerMidStackFunctor::operator()):
(JSC::FindCallerMidStackFunctor::getCallerFrame):
(JSC::DebuggerCallFrame::callerFrame):

  • interpreter/VMInspector.cpp:

(JSC::CountFramesFunctor::CountFramesFunctor):
(JSC::CountFramesFunctor::operator()):
(JSC::CountFramesFunctor::count):
(JSC::VMInspector::countFrames):

  • runtime/VM.cpp:

(JSC::VM::VM):
(JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
(JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
(JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame):
(JSC::FindFirstCallerFrameWithCodeblockFunctor::index):
(JSC::VM::throwException):
Changed unwinding to use StackVisitor including added functor classes.

  • interpreter/CallFrame.cpp:

(JSC::CallFrame::callerFrame):
Added new flavor of callerFrame() that can iteratively unwind the stack.

  • interpreter/CallFrame.h:

(JSC::ExecState::callerFrame): Changed callerFrame() to use private common helper.
(JSC::ExecState::callerFrameOrVMEntryFrame): Deleted.
(JSC::ExecState::isVMEntrySentinel): Deleted.
(JSC::ExecState::vmEntrySentinelCallerFrame): Deleted.
(JSC::ExecState::initializeVMEntrySentinelFrame): Deleted.
(JSC::ExecState::callerFrameSkippingVMEntrySentinel): Deleted.
(JSC::ExecState::vmEntrySentinelCodeBlock): Deleted.

  • interpreter/CallFrame.h:

(JSC::ExecState::init):
(JSC::ExecState::topOfFrame):
(JSC::ExecState::currentVPC):
(JSC::ExecState::setCurrentVPC):
Eliminated unneded checking of sentinel frame.

  • interpreter/Interpreter.cpp:

(JSC::unwindCallFrame):
(JSC::Interpreter::getStackTrace): Updated for unwidning changes.
(JSC::Interpreter::unwind): Eliminated unneeded sentinel frame check.

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):

  • jit/JITStubs.h:
  • llint/LLIntThunks.cpp:

(JSC::callToJavaScript): Deleted.
(JSC::callToNativetion): Deleted.
(JSC::vmEntryToJavaScript):
(JSC::vmEntryToNative):

  • llint/LLIntThunks.h:

Updated for vmEntryToJavaScript and vmEntryToNative name changes.

  • interpreter/Interpreter.h:

(JSC::TopCallFrameSetter::TopCallFrameSetter):
(JSC::TopCallFrameSetter::~TopCallFrameSetter):
Eliminated unneeded sentinel frame check.

  • interpreter/Interpreter.h:

(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
Removed sentinel specific constructor.

  • interpreter/StackVisitor.cpp:

(JSC::StackVisitor::StackVisitor):
(JSC::StackVisitor::readFrame):
(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::readInlinedFrame):
(JSC::StackVisitor::Frame::print):

  • interpreter/StackVisitor.h:

(JSC::StackVisitor::Frame::callerIsVMEntry):
Changes for unwinding using CallFrame::callerFrame(VMEntryFrame*&). Also added field that
indicates when about to step over a VM entry frame.

  • interpreter/VMEntryRecord.h: Added.

(JSC::VMEntryRecord::prevTopCallFrame):
(JSC::VMEntryRecord::prevTopVMEntryFrame):
New struct to record prior state of VM's notion of VM entry and top call frames.

  • jit/JITCode.cpp:

(JSC::JITCode::execute):
Use new vmEntryToJavaScript and vmEntryToNative name.

  • llint/LLIntOffsetsExtractor.cpp: Added include for VMEntryRecord.h.
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:

Offline assembly implementation of creating stack frame with VMEntryRecord and well as restoring
relevent VM fields when exiting the VM. Added a helper that returns a VMEntryRecord given
a pointer to the VM entry frame.

  • llint/LLIntThunks.cpp:

(JSC::vmEntryRecord):

  • llint/LowLevelInterpreter.cpp:

(JSC::CLoop::execute):
C Loop changes to mirror the assembly changes.

  • runtime/VM.h:

Added topVMEntryFrame field.

Location:
trunk/Source/JavaScriptCore
Files:
1 added
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r172655 r172665  
     12014-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
    11492014-08-15  Brian J. Burg  <burg@cs.washington.edu>
    2150
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r172655 r172665  
    12721272    <ClInclude Include="..\interpreter\CallFrameInlines.h" />
    12731273    <ClInclude Include="..\interpreter\CallFrameClosure.h" />
     1274    <ClInclude Include="..\interpreter\VMEntryRecord.h" />
    12741275    <ClInclude Include="..\interpreter\Interpreter.h" />
    12751276    <ClInclude Include="..\interpreter\JSStack.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r172655 r172665  
    22142214      <Filter>interpreter</Filter>
    22152215    </ClInclude>
     2216    <ClInclude Include="..\interpreter\VMEntryRecord.h">
     2217      <Filter>interpreter</Filter>
     2218    </ClInclude>
    22162219    <ClInclude Include="..\interpreter\Interpreter.h">
    22172220      <Filter>interpreter</Filter>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r172655 r172665  
    11571157                6553A33217A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6553A33017A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h */; };
    11581158                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, ); }; };
    11591160                65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */; };
    11601161                65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */; };
     
    28862887                1429D8840ED21C3D00B89619 /* SamplingTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingTool.h; sourceTree = "<group>"; };
    28872888                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; };
    28892890                1429D92D0ED22D7000B89619 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JIT.cpp; sourceTree = "<group>"; };
    28902891                1429D92E0ED22D7000B89619 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; };
     
    30723073                65621E6C089E859700760F35 /* PropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = PropertySlot.h; sourceTree = "<group>"; tabWidth = 8; };
    30733074                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; };
    30743076                65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilationInfo.h; path = dfg/DFGOSRExitCompilationInfo.h; sourceTree = "<group>"; };
    30753077                65987F2F16828A7E003C2F8D /* UnusedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedPointer.h; sourceTree = "<group>"; };
     
    31143116                8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeProfiling.cpp; sourceTree = "<group>"; };
    31153117                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>"; };
    31173119                8606DDE918DA44AB00A383D0 /* IdentifierInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdentifierInlines.h; sourceTree = "<group>"; };
    31183120                8612E4CB1522918400C836BE /* MatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchResult.h; sourceTree = "<group>"; };
     
    31433145                869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
    31443146                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>"; };
    31473149                86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
    31483150                86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
     
    35333535                A7C1EAEA17987AB600299DB2 /* CallFrameInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrameInlines.h; sourceTree = "<group>"; };
    35343536                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; };
    35363538                A7C1EAED17987AB600299DB2 /* StackVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackVisitor.h; sourceTree = "<group>"; };
    35373539                A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; };
     
    37553757                E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
    37563758                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; };
    37593761                E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCacheItem.h; sourceTree = "<group>"; };
    37603762                E49DC15112EF272200184A1F /* SourceProviderCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCache.h; sourceTree = "<group>"; };
     
    41764178                        isa = PBXGroup;
    41774179                        children = (
     4180                                658D3A5519638268003C45D6 /* VMEntryRecord.h */,
    41784181                                0F55F0F114D1063600AC7649 /* AbstractPC.cpp */,
    41794182                                0F55F0F214D1063600AC7649 /* AbstractPC.h */,
     
    60186021                                A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
    60196022                                86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
     6023                                658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */,
    60206024                                2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */,
    60216025                                147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r172614 r172665  
    140140            { "name" : "getHostCallReturnValue" },
    141141            { "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" },
    144144            { "name" : "llint_cloop_did_return_from_js_1" },
    145145            { "name" : "llint_cloop_did_return_from_js_2" },
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r172614 r172665  
    6060#include "RepatchBuffer.h"
    6161#include "SlotVisitorInlines.h"
     62#include "StackVisitor.h"
    6263#include "UnlinkedInstructionStream.h"
    6364#include <wtf/BagToHashMap.h>
     
    31603161}
    31613162
     3163class RecursionCheckFunctor {
     3164public:
     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
     3195private:
     3196    CallFrame* m_startCallFrame;
     3197    CodeBlock* m_codeBlock;
     3198    unsigned m_depthToCheck;
     3199    bool m_foundStartCallFrame;
     3200    bool m_didRecurse;
     3201};
     3202
    31623203void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
    31633204{
     
    32073248        return;
    32083249    }
    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
    32233262    RELEASE_ASSERT(callerCodeBlock->m_capabilityLevelState != DFG::CapabilityLevelNotSet);
    32243263   
  • trunk/Source/JavaScriptCore/debugger/Debugger.cpp

    r172324 r172665  
    608608        return;
    609609
    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;
    611612    notifyDoneProcessingDebuggerEvents();
    612613}
     
    724725
    725726    // 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);
    730734}
    731735
     
    757761        return;
    758762    if (m_currentCallFrame == m_pauseOnCallFrame) {
    759         m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
     763        VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
     764        m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
    760765        if (!m_currentCallFrame)
    761766            return;
    762767    }
    763     m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel();
     768    VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame;
     769    m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame);
    764770}
    765771
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r172372 r172665  
    5656};
    5757
     58class FindCallerMidStackFunctor {
     59public:
     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
     76private:
     77    CallFrame* m_callFrame;
     78    CallFrame* m_callerFrame;
     79};
     80
    5881DebuggerCallFrame::DebuggerCallFrame(CallFrame* callFrame)
    5982    : m_callFrame(callFrame)
     
    7194        return m_caller;
    7295
    73     CallFrame* callerFrame = m_callFrame->callerFrameSkippingVMEntrySentinel();
     96    FindCallerMidStackFunctor functor(m_callFrame);
     97    m_callFrame->vm().topCallFrame->iterate(functor);
     98
     99    CallFrame* callerFrame = functor.getCallerFrame();
    74100    if (!callerFrame)
    75101        return 0;
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp

    r170421 r172665  
    137137}
    138138
     139CallFrame* 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
    139149JSActivation* CallFrame::activation() const
    140150{
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r171824 r172665  
    3030#include "Register.h"
    3131#include "StackVisitor.h"
     32#include "VMEntryRecord.h"
    3233
    3334namespace JSC  {
     
    9596        CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
    9697
    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
    98102        static ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); }
    99103
     
    162166        Register* topOfFrame()
    163167        {
    164             if (isVMEntrySentinel() || !codeBlock())
     168            if (!codeBlock())
    165169                return registers();
    166170            return topOfFrameInternal();
     
    170174        Instruction* currentVPC() const
    171175        {
    172             ASSERT(!isVMEntrySentinel());
    173176            return bitwise_cast<Instruction*>(this[JSStack::ArgumentCount].tag());
    174177        }
    175178        void setCurrentVPC(Instruction* vpc)
    176179        {
    177             ASSERT(!isVMEntrySentinel());
    178180            this[JSStack::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc);
    179181        }
     
    190192            CallFrame* callerFrame, int argc, JSObject* callee)
    191193        {
    192             ASSERT(callerFrame == noCaller() || callerFrame->isVMEntrySentinel() || callerFrame->stack()->containsAddress(this));
     194            ASSERT(callerFrame == noCaller() || callerFrame->stack()->containsAddress(this));
    193195
    194196            setCodeBlock(codeBlock);
     
    246248        static CallFrame* noCaller() { return 0; }
    247249
    248         bool isVMEntrySentinel() const
    249         {
    250             return !!this && codeBlock() == vmEntrySentinelCodeBlock();
    251         }
    252 
    253         CallFrame* vmEntrySentinelCallerFrame() const
    254         {
    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 
    277250        void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[JSStack::ArgumentCount].payload() = count; }
    278251        void setCallee(JSObject* callee) { static_cast<Register*>(this)[JSStack::Callee] = Register::withCallee(callee); }
     
    292265
    293266    private:
    294         static const intptr_t s_VMEntrySentinel = 1;
    295267
    296268#ifndef NDEBUG
     
    331303        }
    332304
     305        void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
     306
    333307        CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); }
    334308        const CallerFrameAndPC& callerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
    335 
    336         static CodeBlock* vmEntrySentinelCodeBlock() { return reinterpret_cast<CodeBlock*>(s_VMEntrySentinel); }
    337309
    338310        friend class JSStack;
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r172176 r172665  
    480480    }
    481481
    482     CallFrame* callerFrame = callFrame->callerFrame();
    483     return !callerFrame->isVMEntrySentinel();
     482    return !visitor->callerIsVMEntryFrame();
    484483}
    485484
     
    598597{
    599598    VM& vm = m_vm;
    600     ASSERT(!vm.topCallFrame->isVMEntrySentinel());
    601599    CallFrame* callFrame = vm.topCallFrame;
    602600    if (!callFrame)
     
    684682NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& exceptionValue)
    685683{
    686     if (callFrame->isVMEntrySentinel()) {
    687         // This happens when we throw stack overflow in a function that is called
    688         // directly from callToJavaScript. Stack overflow throws the exception in the
    689         // context of the caller. In that case the caller is the sentinel frame. The
    690         // right thing to do is to pretend that the exception is uncaught so that we
    691         // go to the uncaught exception handler, which returns through callToJavaScript.
    692         return 0;
    693     }
    694    
    695684    CodeBlock* codeBlock = callFrame->codeBlock();
    696685    ASSERT(codeBlock);
     
    997986            result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame);
    998987        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));
    1000989            if (callFrame->hadException())
    1001990                result = jsNull();
     
    10651054            result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame);
    10661055        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));
    10681057
    10691058            if (!callFrame->hadException())
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r170147 r172665  
    158158            , oldCallFrame(currentVM.topCallFrame)
    159159        {
    160             ASSERT(!callFrame->isVMEntrySentinel());
    161160            currentVM.topCallFrame = callFrame;
    162161        }
     
    164163        ~TopCallFrameSetter()
    165164        {
    166             ASSERT(!oldCallFrame->isVMEntrySentinel());
    167165            vm.topCallFrame = oldCallFrame;
    168166        }
     
    178176            ASSERT(vm);
    179177            ASSERT(callFrame);
    180             ASSERT(!callFrame->isVMEntrySentinel());
    181178            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;
    191179        }
    192180    };
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp

    r171213 r172665  
    3939{
    4040    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;
    4146    readFrame(startFrame);
    4247}
     
    5762void StackVisitor::readFrame(CallFrame* callFrame)
    5863{
    59     ASSERT(!callFrame->isVMEntrySentinel());
    6064    if (!callFrame) {
    6165        m_frame.setToEnd();
     
    105109    m_frame.m_callFrame = callFrame;
    106110    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;
    108114    m_frame.m_callee = callFrame->callee();
    109115    m_frame.m_scope = callFrame->scope();
     
    128134{
    129135    ASSERT(codeOrigin);
    130     ASSERT(!callFrame->isVMEntrySentinel());
    131136
    132137    int frameOffset = inlinedFrameOffset(codeOrigin);
     
    381386    printif(i, "   name '%s'\n", functionName().utf8().data());
    382387    printif(i, "   sourceURL '%s'\n", sourceURL().utf8().data());
    383     printif(i, "   isVMEntrySentinel %d\n", callerFrame->isVMEntrySentinel());
    384388
    385389#if ENABLE(DFG_JIT)
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.h

    r156984 r172665  
    2727#define StackVisitor_h
    2828
     29#include "VMEntryRecord.h"
    2930#include <wtf/text/WTFString.h>
    3031
     
    5758        size_t index() const { return m_index; }
    5859        size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis; }
     60        bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; }
    5961        CallFrame* callerFrame() const { return m_callerFrame; }
    6062        JSObject* callee() const { return m_callee; }
     
    9597        size_t m_index;
    9698        size_t m_argumentCountIncludingThis;
     99        VMEntryFrame* m_VMEntryFrame;
    97100        CallFrame* m_callerFrame;
    98101        JSObject* m_callee;
     
    100103        CodeBlock* m_codeBlock;
    101104        unsigned m_bytecodeOffset;
     105        bool m_callerIsVMEntryFrame;
    102106#if ENABLE(DFG_JIT)
    103107        InlineCallFrame* m_inlineCallFrame;
  • trunk/Source/JavaScriptCore/interpreter/VMInspector.cpp

    r163844 r172665  
    3030
    3131#include "JSCInlines.h"
     32#include "StackVisitor.h"
    3233#include <wtf/ASCIICType.h>
    3334#include <wtf/text/WTFString.h>
     
    100101}
    101102
     103class CountFramesFunctor {
     104public:
     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
     117private:
     118    unsigned m_count;
     119};
     120
    102121int VMInspector::countFrames(CallFrame* frame)
    103122{
    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();
    110127}
    111128
  • trunk/Source/JavaScriptCore/jit/JITCode.cpp

    r163844 r172665  
    4545JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame)
    4646{
    47     JSValue result = JSValue::decode(callToJavaScript(executableAddress(), vm, protoCallFrame));
     47    JSValue result = JSValue::decode(vmEntryToJavaScript(executableAddress(), vm, protoCallFrame));
    4848    return vm->exception() ? jsNull() : result;
    4949}
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r172614 r172665  
    8181    // We pass in our own code block, because the callframe hasn't been populated.
    8282    VM* vm = codeBlock->vm();
    83     CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
     83
     84    VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame;
     85    CallFrame* callerFrame = exec->callerFrame(topVMEntryFrame);
    8486    if (!callerFrame)
    8587        callerFrame = exec;
     
    9395{
    9496    VM* vm = &exec->vm();
    95     CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
     97    VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame;
     98    CallFrame* callerFrame = exec->callerFrame(topVMEntryFrame);
    9699    NativeCallFrameTracer tracer(vm, callerFrame);
    97100
     
    108111{
    109112    VM* vm = &exec->vm();
    110     CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
     113    VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame;
     114    CallFrame* callerFrame = exec->callerFrame(topVMEntryFrame);
    111115    NativeCallFrameTracer tracer(vm, callerFrame);
    112116
     
    18241828void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
    18251829{
    1826     NativeCallFrameTracer tracer(vm, exec, NativeCallFrameTracer::VMEntrySentinelOK);
     1830    NativeCallFrameTracer tracer(vm, exec);
    18271831
    18281832    JSValue exceptionValue = vm->exception();
     
    18381842    NativeCallFrameTracer tracer(vm, exec);
    18391843
    1840     ASSERT(!exec->isVMEntrySentinel());
    18411844    genericUnwind(vm, exec, vm->exception());
    18421845}
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r167094 r172665  
    4242
    4343extern "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*);
    4646}
    4747#endif
  • trunk/Source/JavaScriptCore/jsc.cpp

    r172152 r172665  
    688688EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
    689689{
    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);
    692694    return JSValue::encode(jsUndefined());
    693695}
  • trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp

    r172176 r172665  
    5050#include "Structure.h"
    5151#include "StructureChain.h"
     52#include "VMEntryRecord.h"
    5253#include "ValueProfile.h"
    5354#include <wtf/text/StringImpl.h>
  • trunk/Source/JavaScriptCore/llint/LLIntThunks.cpp

    r170876 r172665  
    3838#include "LowLevelInterpreter.h"
    3939#include "ProtoCallFrame.h"
     40#include "StackAlignment.h"
    4041#include "VM.h"
    4142
     
    9495// Non-JIT (i.e. C Loop LLINT) case:
    9596
    96 EncodedJSValue callToJavaScript(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
     97EncodedJSValue vmEntryToJavaScript(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
    9798{
    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);
    99100    return JSValue::encode(result);
    100101}
    101102
    102 EncodedJSValue callToNativeFunction(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
     103EncodedJSValue vmEntryToNative(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)
    103104{
    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);
    105106    return JSValue::encode(result);
    106107}
     108
     109extern "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
    107117
    108118#endif // ENABLE(JIT)
  • trunk/Source/JavaScriptCore/llint/LLIntThunks.h

    r170147 r172665  
    3535
    3636extern "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*);
    3939}
    4040
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r172614 r172665  
    4343const SlotSize = 8
    4444
     45const StackAlignment = 16
     46const StackAlignmentMask = StackAlignment - 1
     47
    4548const CallerFrameAndPCSize = 2 * PtrSize
    4649
     
    236239            # ARM can't do logical ops with the sp as a source
    237240            move sp, tempReg
    238             andp 0xf, tempReg
     241            andp StackAlignmentMask, tempReg
    239242        else
    240             andp sp, 0xf, tempReg
     243            andp sp, StackAlignmentMask, tempReg
    241244        end
    242245        btpz tempReg, .stackPointerOkay
     
    246249    end
    247250end
     251
     252if C_LOOP
     253    const CalleeSaveRegisterCount = 0
     254elsif ARM or ARMv7_TRADITIONAL or ARMv7
     255    const CalleeSaveRegisterCount = 7
     256elsif ARM64 or MIPS
     257    const CalleeSaveRegisterCount = 10
     258elsif SH4 or X86_64
     259    const CalleeSaveRegisterCount = 5
     260elsif X86 or X86_WIN
     261    const CalleeSaveRegisterCount = 3
     262elsif X86_64_WIN
     263    const CalleeSaveRegisterCount = 7
     264end
     265
     266const 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
     270const VMEntryTotalFrameSize = (CalleeRegisterSaveSize + sizeof VMEntryRecord + StackAlignment - 1) & ~StackAlignmentMask
    248271
    249272macro pushCalleeSaves()
     
    418441end
    419442
    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
     443macro vmEntryRecord(entryFramePointer, resultReg)
     444    subp entryFramePointer, VMEntryTotalFrameSize, resultReg
    487445end
    488446
     
    729687
    730688# 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)
    733691
    734692if C_LOOP
    735 _llint_call_to_javascript:
     693_llint_vm_entry_to_javascript:
    736694else
    737 global _callToJavaScript
    738 _callToJavaScript:
    739 end
    740     doCallToJavaScript(makeJavaScriptCall)
     695global _vmEntryToJavaScript
     696_vmEntryToJavaScript:
     697end
     698    doVMEntry(makeJavaScriptCall)
    741699
    742700
    743701if C_LOOP
    744 _llint_call_to_native_function:
     702_llint_vm_entry_to_native:
    745703else
    746 global _callToNativeFunction
    747 _callToNativeFunction:
    748 end
    749     doCallToJavaScript(makeHostFunctionCall)
     704global _vmEntryToNative
     705_vmEntryToNative:
     706end
     707    doVMEntry(makeHostFunctionCall)
    750708
    751709
     
    790748    storep address, VM::m_lastStackTop[vm]
    791749    ret
    792 end
    793 
     750
     751if C_LOOP
     752else
     753# VMEntryRecord* vmEntryRecord(const VMEntryFrame* entryFrame)
     754global _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
     773end
     774end
    794775
    795776if C_LOOP
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp

    r170147 r172665  
    339339#endif
    340340
    341     // Initialize the incoming args for doCallToJavaScript:
     341    // Initialize the incoming args for doVMEntryToJavaScript:
    342342    t0.vp = executableAddress;
    343343    t1.vm = vm;
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r172598 r172665  
    156156end
    157157
    158 macro doCallToJavaScript(makeCall)
     158macro doVMEntry(makeCall)
    159159    if X86 or X86_WIN
    160160        const entry = t4
     
    162162        const protoCallFrame = t5
    163163
    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
    168166        const temp3 = t2
    169167        const temp4 = t3 # same as vm
     
    173171        const protoCallFrame = a2
    174172
    175         const previousCFR = t3
    176         const previousPC = lr
    177         const temp1 = t3 # Same as previousCFR
     173        const temp1 = t3
    178174        const temp2 = t4
    179175        const temp3 = t5
     
    185181        const topOfStack = a3
    186182
    187         const previousCFR = t2
    188         const previousPC = lr
    189183        const temp1 = t3
    190184        const temp2 = t5
     
    196190        const protoCallFrame = a2
    197191
    198         const previousCFR = t3
    199         const previousPC = lr
    200         const temp1 = t3 # Same as previousCFR
     192        const temp1 = t3
    201193        const temp2 = a3
    202194        const temp3 = t8
     
    204196    end
    205197
    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
    216204    end
    217205
    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]
    227209    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
    236223    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
    244227    end
    245228
     
    247230    addp CallFrameHeaderSlots, temp2, temp2
    248231    lshiftp 3, temp2
    249     subp cfr, temp2, temp1
     232    subp sp, temp2, temp1
    250233
    251234    # Ensure that we have enough additional stack capacity for the incoming args,
     
    253236    # before we start copying the args from the protoCallFrame below.
    254237    bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
    255 
    256     if ARMv7
    257         subp cfr, 8, temp2
    258         move temp2, sp
    259     else
    260         subp cfr, 8, sp
    261     end
    262238
    263239    if C_LOOP
     
    276252
    277253    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()
    279267    ret
    280268
     
    317305.copyArgsDone:
    318306    storep sp, VM::topCallFrame[vm]
     307    storep cfr, VM::topVMEntryFrame[vm]
    319308
    320309    makeCall(entry, temp1, temp2)
    321310
    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
    328315    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()
    331323    ret
    332324end
     
    379371    loadp VM::callFrameForThrow[t3], cfr
    380372
    381     # So far, we've unwound the stack to the frame just below the sentinel frame, except
    382     # 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 for
    384     # returning to the caller C frame.
    385     bpeq CodeBlock[cfr], 1, .handleUncaughtExceptionAlreadyIsSentinel
    386373    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
    391379    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()
    394387    ret
    395388
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r172598 r172665  
    139139end
    140140
    141 macro doCallToJavaScript(makeCall)
     141macro doVMEntry(makeCall)
    142142    if X86_64
    143143        const entry = t4
     
    172172    end
    173173
    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)
    186178
    187179    checkStackPointerAlignment(temp2, 0xbad0dc01)
    188180
    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]
    196182    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]
    202186
    203187    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
    204188    addp CallFrameHeaderSlots, temp2, temp2
    205189    lshiftp 3, temp2
    206     subp cfr, temp2, temp1
     190    subp sp, temp2, temp1
    207191
    208192    # Ensure that we have enough additional stack capacity for the incoming args,
     
    210194    # before we start copying the args from the protoCallFrame below.
    211195    bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
    212 
    213     move cfr, sp
    214196
    215197    if C_LOOP
     
    228210
    229211    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()
    231225    ret
    232226
     
    270264        storep sp, VM::topCallFrame[vm]
    271265    end
     266    storep cfr, VM::topVMEntryFrame[vm]
    272267
    273268    move 0xffff000000000000, csr1
     
    280275    checkStackPointerAlignment(temp3, 0xbad0dc03)
    281276
    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()
    296289
    297290    ret
     
    347340    loadp VM::callFrameForThrow[t3], cfr
    348341
    349     # So far, we've unwound the stack to the frame just below the sentinel frame, except
    350     # 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 for
    352     # returning to the caller C frame.
    353     bpeq CodeBlock[cfr], 1, .handleUncaughtExceptionAlreadyIsSentinel
    354342    loadp CallerFrame[cfr], cfr
    355 .handleUncaughtExceptionAlreadyIsSentinel:
    356 
    357     loadp Callee[cfr], t3 # VM
    358     loadp ScopeChain[cfr], t5 # previous topCallFrame
     343    vmEntryRecord(cfr, t2)
     344
     345    loadp VMEntryRecord::m_vm[t2], t3
     346    loadp VMEntryRecord::m_prevTopCallFrame[t2], t5
    359347    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()
    362355    ret
    363356
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r172614 r172665  
    8181#include "SimpleTypedArrayController.h"
    8282#include "SourceProviderCache.h"
     83#include "StackVisitor.h"
    8384#include "StrictEvalActivation.h"
    8485#include "StrongInlines.h"
     
    150151    , vmType(vmType)
    151152    , clientData(0)
     153    , topVMEntryFrame(nullptr)
    152154    , topCallFrame(CallFrame::noCaller())
    153155    , m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable)
     
    594596    exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
    595597}
    596    
     598
     599class FindFirstCallerFrameWithCodeblockFunctor {
     600public:
     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
     627private:
     628    CallFrame* m_startCallFrame;
     629    CallFrame* m_foundCallFrame;
     630    bool m_foundStartCallFrame;
     631    unsigned m_index;
     632};
     633
    597634JSValue VM::throwException(ExecState* exec, JSValue error)
    598635{
     
    632669    }
    633670    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
    640676        if (callFrame && callFrame->codeBlock()) {
    641677            stackFrame = stackTrace.at(stackIndex);
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r172614 r172665  
    4848#include "TypedArrayController.h"
    4949#include "TypeLocation.h"
     50#include "VMEntryRecord.h"
    5051#include "Watchdog.h"
    5152#include "Watchpoint.h"
     
    236237        VMType vmType;
    237238        ClientData* clientData;
     239        VMEntryFrame* topVMEntryFrame;
    238240        ExecState* topCallFrame;
    239241        std::unique_ptr<Watchdog> watchdog;
Note: See TracChangeset for help on using the changeset viewer.