Changeset 160094 in webkit


Ignore:
Timestamp:
Dec 4, 2013 8:40:17 AM (10 years ago)
Author:
msaboff@apple.com
Message:

Move the setting up of callee's callFrame from pushFrame to callToJavaScript thunk
https://bugs.webkit.org/show_bug.cgi?id=123999

Reviewed by Filip Pizlo.

Changed LLInt and/or JIT enabled ports to allocate the stack frame in the
callToJavaScript stub. Added an additional stub, callToNativeFunction that
allocates a stack frame in a similar way for calling native entry points
that take a single ExecState* argument. These stubs are implemented
using common macros in LowLevelInterpreter{32_64,64}.asm. There are also
Windows X86 and X86-64 versions in the corresponding JitStubsXX.h.
The stubs allocate and create a sentinel frame, then create the callee's
frame, populating the header and arguments from the passed in ProtoCallFrame*.
It is assumed that the caller of either stub does a check for enough stack space
via JSStack::entryCheck().

For ports using the C-Loop interpreter, the prior method for allocating stack
frame and invoking functions is used, namely with JSStack::pushFrame() and
::popFrame().

Made spelling changes "sentinal" -> "sentinel".

(JSC::CachedCall::CachedCall):
(JSC::CachedCall::setThis):
(JSC::CachedCall::setArgument):

  • interpreter/CallFrameClosure.h:

(JSC::CallFrameClosure::resetCallFrame):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):

  • interpreter/Interpreter.h:
  • interpreter/JSStack.h:
  • interpreter/JSStackInlines.h:

(JSC::JSStack::entryCheck):
(JSC::JSStack::pushFrame):
(JSC::JSStack::popFrame):

  • interpreter/ProtoCallFrame.cpp: Added.

(JSC::ProtoCallFrame::init):

  • interpreter/ProtoCallFrame.h: Added.

(JSC::ProtoCallFrame::codeBlock):
(JSC::ProtoCallFrame::setCodeBlock):
(JSC::ProtoCallFrame::setScope):
(JSC::ProtoCallFrame::setCallee):
(JSC::ProtoCallFrame::argumentCountIncludingThis):
(JSC::ProtoCallFrame::argumentCount):
(JSC::ProtoCallFrame::setArgumentCountIncludingThis):
(JSC::ProtoCallFrame::setPaddedArgsCount):
(JSC::ProtoCallFrame::clearCurrentVPC):
(JSC::ProtoCallFrame::setThisValue):
(JSC::ProtoCallFrame::setArgument):

  • jit/JITCode.cpp:

(JSC::JITCode::execute):

  • jit/JITCode.h:
  • jit/JITOperations.cpp:
  • jit/JITStubs.h:
  • jit/JITStubsMSVC64.asm:
  • jit/JITStubsX86.h:
  • llint/LLIntOffsetsExtractor.cpp:
  • llint/LLIntThunks.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/ArgList.h:

(JSC::ArgList::data):

  • runtime/JSArray.cpp:

(JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):

  • runtime/StringPrototype.cpp:

(JSC::replaceUsingRegExpSearch):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r159605 r160094  
    218218    interpreter/Interpreter.cpp
    219219    interpreter/JSStack.cpp
     220    interpreter/ProtoCallFrame.cpp
    220221    interpreter/StackVisitor.cpp
    221222    interpreter/VMInspector.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r160092 r160094  
     12013-12-04  Michael Saboff  <msaboff@apple.com>
     2
     3        Move the setting up of callee's callFrame from pushFrame to callToJavaScript thunk
     4        https://bugs.webkit.org/show_bug.cgi?id=123999
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Changed LLInt and/or JIT enabled ports to allocate the stack frame in the
     9        callToJavaScript stub.  Added an additional stub, callToNativeFunction that
     10        allocates a stack frame in a similar way for calling native entry points
     11        that take a single ExecState* argument.  These stubs are implemented
     12        using common macros in LowLevelInterpreter{32_64,64}.asm.  There are also
     13        Windows X86 and X86-64 versions in the corresponding JitStubsXX.h.
     14        The stubs allocate and create a sentinel frame, then create the callee's
     15        frame, populating  the header and arguments from the passed in ProtoCallFrame*.
     16        It is assumed that the caller of either stub does a check for enough stack space
     17        via JSStack::entryCheck().
     18
     19        For ports using the C-Loop interpreter, the prior method for allocating stack
     20        frame and invoking functions is used, namely with JSStack::pushFrame() and
     21        ::popFrame().
     22
     23        Made spelling changes "sentinal" -> "sentinel".
     24
     25        * CMakeLists.txt:
     26        * GNUmakefile.list.am:
     27        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     28        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     29        * JavaScriptCore.xcodeproj/project.pbxproj:
     30        * interpreter/CachedCall.h:
     31        (JSC::CachedCall::CachedCall):
     32        (JSC::CachedCall::setThis):
     33        (JSC::CachedCall::setArgument):
     34        * interpreter/CallFrameClosure.h:
     35        (JSC::CallFrameClosure::resetCallFrame):
     36        * interpreter/Interpreter.cpp:
     37        (JSC::Interpreter::execute):
     38        (JSC::Interpreter::executeCall):
     39        (JSC::Interpreter::executeConstruct):
     40        (JSC::Interpreter::prepareForRepeatCall):
     41        * interpreter/Interpreter.h:
     42        * interpreter/JSStack.h:
     43        * interpreter/JSStackInlines.h:
     44        (JSC::JSStack::entryCheck):
     45        (JSC::JSStack::pushFrame):
     46        (JSC::JSStack::popFrame):
     47        * interpreter/ProtoCallFrame.cpp: Added.
     48        (JSC::ProtoCallFrame::init):
     49        * interpreter/ProtoCallFrame.h: Added.
     50        (JSC::ProtoCallFrame::codeBlock):
     51        (JSC::ProtoCallFrame::setCodeBlock):
     52        (JSC::ProtoCallFrame::setScope):
     53        (JSC::ProtoCallFrame::setCallee):
     54        (JSC::ProtoCallFrame::argumentCountIncludingThis):
     55        (JSC::ProtoCallFrame::argumentCount):
     56        (JSC::ProtoCallFrame::setArgumentCountIncludingThis):
     57        (JSC::ProtoCallFrame::setPaddedArgsCount):
     58        (JSC::ProtoCallFrame::clearCurrentVPC):
     59        (JSC::ProtoCallFrame::setThisValue):
     60        (JSC::ProtoCallFrame::setArgument):
     61        * jit/JITCode.cpp:
     62        (JSC::JITCode::execute):
     63        * jit/JITCode.h:
     64        * jit/JITOperations.cpp:
     65        * jit/JITStubs.h:
     66        * jit/JITStubsMSVC64.asm:
     67        * jit/JITStubsX86.h:
     68        * llint/LLIntOffsetsExtractor.cpp:
     69        * llint/LLIntThunks.h:
     70        * llint/LowLevelInterpreter.asm:
     71        * llint/LowLevelInterpreter32_64.asm:
     72        * llint/LowLevelInterpreter64.asm:
     73        * runtime/ArgList.h:
     74        (JSC::ArgList::data):
     75        * runtime/JSArray.cpp:
     76        (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
     77        * runtime/StringPrototype.cpp:
     78        (JSC::replaceUsingRegExpSearch):
     79
    1802013-12-04  László Langó  <lango@inf.u-szeged.hu>
    281
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r159943 r160094  
    623623        Source/JavaScriptCore/interpreter/JSStack.h \
    624624        Source/JavaScriptCore/interpreter/JSStackInlines.h \
     625        Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp \
     626        Source/JavaScriptCore/interpreter/ProtoCallFrame.h \
    625627        Source/JavaScriptCore/interpreter/Register.h \
    626628        Source/JavaScriptCore/interpreter/StackVisitor.cpp \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r160062 r160094  
    460460    <ClCompile Include="..\interpreter\Interpreter.cpp" />
    461461    <ClCompile Include="..\interpreter\JSStack.cpp" />
     462    <ClCompile Include="..\interpreter\ProtoCallFrame.cpp" />
    462463    <ClCompile Include="..\interpreter\StackVisitor.cpp" />
    463464    <ClCompile Include="..\interpreter\VMInspector.cpp" />
     
    10041005    <ClInclude Include="..\interpreter\JSStack.h" />
    10051006    <ClInclude Include="..\interpreter\JSStackInlines.h" />
     1007    <ClInclude Include="..\interpreter\ProtoCallFrame.h" />
    10061008    <ClInclude Include="..\interpreter\Register.h" />
    10071009    <ClInclude Include="..\interpreter\StackVisitor.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r160062 r160094  
    289289      <Filter>interpreter</Filter>
    290290    </ClCompile>
     291    <ClCompile Include="..\interpreter\ProtoCallFrame.cpp">
     292      <Filter>interpreter</Filter>
     293    </ClCompile>
    291294    <ClCompile Include="..\interpreter\StackVisitor.cpp">
    292295      <Filter>interpreter</Filter>
     
    17261729    </ClInclude>
    17271730    <ClInclude Include="..\interpreter\JSStackInlines.h">
     1731      <Filter>interpreter</Filter>
     1732    </ClInclude>
     1733    <ClInclude Include="..\interpreter\ProtoCallFrame.h">
    17281734      <Filter>interpreter</Filter>
    17291735    </ClInclude>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r159943 r160094  
    736736                65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */; };
    737737                65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C0285B1717966800351E35 /* ARMv7DOpcode.h */; };
     738                65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */; };
    738739                7C15F65D17C199CE00794D40 /* JSPromiseCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C15F65B17C199CE00794D40 /* JSPromiseCallback.cpp */; };
    739740                7C15F65E17C199CE00794D40 /* JSPromiseCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C15F65C17C199CE00794D40 /* JSPromiseCallback.h */; };
     
    20162017                65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CommonIdentifiers.cpp; sourceTree = "<group>"; };
    20172018                65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
     2019                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtoCallFrame.h; sourceTree = "<group>"; };
     2020                65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; };
    20182021                704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
    20192022                7C15F65B17C199CE00794D40 /* JSPromiseCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseCallback.cpp; sourceTree = "<group>"; };
     
    29192922                        isa = PBXGroup;
    29202923                        children = (
     2924                                65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */,
     2925                                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */,
    29212926                                0F55F0F114D1063600AC7649 /* AbstractPC.cpp */,
    29222927                                0F55F0F214D1063600AC7649 /* AbstractPC.h */,
     
    52785283                        buildActionMask = 2147483647;
    52795284                        files = (
     5285                                65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */,
    52805286                                0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */,
    52815287                                0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
  • trunk/Source/JavaScriptCore/interpreter/CachedCall.h

    r159605 r160094  
    3232#include "JSGlobalObject.h"
    3333#include "Interpreter.h"
     34#include "ProtoCallFrame.h"
    3435#include "VMEntryScope.h"
    3536
     
    4445        {
    4546            ASSERT(!function->isHostFunction());
    46             if (callFrame->vm().isSafeToRecurse())
     47            if (callFrame->vm().isSafeToRecurse()) {
     48#if !ENABLE(LLINT_C_LOOP)
     49                m_arguments.resize(argumentCount);
     50                m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, &m_protoCallFrame, function, argumentCount + 1, function->scope(), m_arguments.data());
     51#else
    4752                m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argumentCount + 1, function->scope());
    48             else
     53#endif
     54            } else
    4955                throwStackOverflowError(callFrame);
    5056            m_valid = !callFrame->hadException();
     
    5662            return m_interpreter->execute(m_closure);
    5763        }
     64#if !ENABLE(LLINT_C_LOOP)
     65        void setThis(JSValue v) { m_protoCallFrame.setThisValue(v); }
     66        void setArgument(int n, JSValue v) { m_protoCallFrame.setArgument(n, v); }
     67#else
    5868        void setThis(JSValue v) { m_closure.setThis(v); }
    5969        void setArgument(int n, JSValue v) { m_closure.setArgument(n, v); }
     
    7181                m_interpreter->endRepeatCall(m_closure);
    7282        }
    73        
     83#endif
     84
    7485    private:
    7586        bool m_valid;
    7687        Interpreter* m_interpreter;
    7788        VMEntryScope m_entryScope;
     89#if !ENABLE(LLINT_C_LOOP)
     90        ProtoCallFrame m_protoCallFrame;
     91        Vector<JSValue> m_arguments;
     92#endif
    7893        CallFrameClosure m_closure;
    7994    };
  • trunk/Source/JavaScriptCore/interpreter/CallFrameClosure.h

    r148696 r160094  
    2727#define CallFrameClosure_h
    2828
     29#include "ProtoCallFrame.h"
     30
    2931namespace JSC {
    3032
    3133struct CallFrameClosure {
    3234    CallFrame* oldCallFrame;
     35#if ENABLE(LLINT_C_LOOP)
    3336    CallFrame* newCallFrame;
     37#else
     38    ProtoCallFrame* newCallFrame;
     39#endif
    3440    JSFunction* function;
    3541    FunctionExecutable* functionExecutable;
     
    5258    {
    5359        newCallFrame->setScope(scope);
     60#if ENABLE(LLINT_C_LOOP)
    5461        // setArgument() takes an arg index that starts from 0 for the first
    5562        // argument after the 'this' value. Since both argumentCountIncludingThis
    5663        // and parameterCountIncludingThis includes the 'this' value, we need to
    57         // subtract 1 from them to make i a valid argument index for setArgument().
     64        // subtract 1 from them to make it a valid argument index for setArgument().
    5865        for (int i = argumentCountIncludingThis-1; i < parameterCountIncludingThis-1; ++i)
    5966            newCallFrame->setArgument(i, jsUndefined());
     67#endif
    6068    }
    6169};
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r159605 r160094  
    5454#include "JSWithScope.h"
    5555#include "LLIntCLoop.h"
     56#include "LLIntThunks.h"
    5657#include "LegacyProfiler.h"
    5758#include "LiteralParser.h"
     
    6061#include "Operations.h"
    6162#include "Parser.h"
     63#include "ProtoCallFrame.h"
    6264#include "RegExpObject.h"
    6365#include "RegExpPrototype.h"
     
    861863    // Push the call frame for this invocation:
    862864    ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
     865#if ENABLE(LLINT_C_LOOP)
    863866    CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
    864867    if (UNLIKELY(!newCallFrame))
     
    867870    // Set the arguments for the callee:
    868871    newCallFrame->setThisValue(thisObj);
     872#else
     873    if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
     874        return checkedReturn(throwStackOverflowError(callFrame));
     875
     876    ProtoCallFrame protoCallFrame;
     877    protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
     878#endif
    869879
    870880    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    880890        result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
    881891#elif ENABLE(JIT)
    882         result = program->generatedJITCode()->execute(&m_stack, newCallFrame, &vm);
     892        result = program->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    883893#endif // ENABLE(JIT)
    884894    }
     
    887897        profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
    888898
     899#if ENABLE(LLINT_C_LOOP)
    889900    m_stack.popFrame(newCallFrame);
     901#endif
    890902
    891903    return checkedReturn(result);
     
    931943        return throwTerminatedExecutionException(callFrame);
    932944
     945#if ENABLE(LLINT_C_LOOP)
    933946    CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
    934947    if (UNLIKELY(!newCallFrame))
     
    939952    for (size_t i = 0; i < args.size(); ++i)
    940953        newCallFrame->setArgument(i, args.at(i));
     954#else
     955    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
     956        return checkedReturn(throwStackOverflowError(callFrame));
     957
     958    ProtoCallFrame protoCallFrame;
     959    protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
     960#endif
    941961
    942962    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    953973            result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
    954974#elif ENABLE(JIT)
    955             result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&m_stack, newCallFrame, &vm);
     975            result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    956976#endif // ENABLE(JIT)
    957         } else
     977        } else {
     978#if ENABLE(LLINT_C_LOOP)
    958979            result = JSValue::decode(callData.native.function(newCallFrame));
     980#else
     981            result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
     982#endif
     983        }
    959984    }
    960985
     
    962987        profiler->didExecute(callFrame, function);
    963988
     989#if ENABLE(LLINT_C_LOOP)
    964990    m_stack.popFrame(newCallFrame);
     991#endif
    965992    return checkedReturn(result);
    966993}
     
    10061033    if (UNLIKELY(vm.watchdog.didFire(callFrame)))
    10071034        return throwTerminatedExecutionException(callFrame);
    1008 
     1035#if ENABLE(LLINT_C_LOOP)
    10091036    CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, constructor);
    10101037    if (UNLIKELY(!newCallFrame))
     
    10151042    for (size_t i = 0; i < args.size(); ++i)
    10161043        newCallFrame->setArgument(i, args.at(i));
     1044#else
     1045    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
     1046        return checkedReturn(throwStackOverflowError(callFrame));
     1047
     1048    ProtoCallFrame protoCallFrame;
     1049    protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
     1050#endif
    10171051
    10181052    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    10291063            result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
    10301064#elif ENABLE(JIT)
    1031             result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&m_stack, newCallFrame, &vm);
     1065            result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    10321066#endif // ENABLE(JIT)
    10331067        } else {
     1068#if ENABLE(LLINT_C_LOOP)
    10341069            result = JSValue::decode(constructData.native.function(newCallFrame));
    1035             if (!callFrame->hadException()) {
    1036                 ASSERT_WITH_MESSAGE(result.isObject(), "Host constructor returned non object.");
    1037                 if (!result.isObject())
    1038                     throwTypeError(newCallFrame);
    1039             }
     1070#else
     1071            result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
     1072#endif
     1073            if (!callFrame->hadException())
     1074                RELEASE_ASSERT(result.isObject());
    10401075        }
    10411076    }
     
    10441079        profiler->didExecute(callFrame, constructor);
    10451080
     1081#if ENABLE(LLINT_C_LOOP)
    10461082    m_stack.popFrame(newCallFrame);
     1083#endif
    10471084
    10481085    if (callFrame->hadException())
     
    10521089}
    10531090
     1091#if ENABLE(LLINT_C_LOOP)
    10541092CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
     1093#else
     1094CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
     1095#endif
    10551096{
    10561097    VM& vm = *scope->vm();
     
    10711112    size_t argsCount = argumentCountIncludingThis;
    10721113
    1073     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function); 
     1114#if ENABLE(LLINT_C_LOOP)
     1115    CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
     1116
    10741117    if (UNLIKELY(!newCallFrame)) {
    10751118        throwStackOverflowError(callFrame);
     
    10771120    }
    10781121
    1079     if (UNLIKELY(!newCallFrame)) {
     1122    // Return the successful closure:
     1123    CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
     1124#else
     1125    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount))) {
    10801126        throwStackOverflowError(callFrame);
    10811127        return CallFrameClosure();
    10821128    }
    10831129
     1130    protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
    10841131    // Return the successful closure:
    1085     CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
     1132    CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
     1133#endif
    10861134    return result;
    10871135}
     
    10971145
    10981146    StackStats::CheckPoint stackCheckPoint;
     1147#if ENABLE(LLINT_C_LOOP)
    10991148    m_stack.validateFence(closure.newCallFrame, "BEFORE");
     1149#endif
    11001150    closure.resetCallFrame();
     1151#if ENABLE(LLINT_C_LOOP)
    11011152    m_stack.validateFence(closure.newCallFrame, "STEP 1");
     1153#endif
    11021154
    11031155    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    11151167    // repeating this call on a second callback function.
    11161168
     1169#if ENABLE(LLINT_C_LOOP)
    11171170    TopCallFrameSetter topCallFrame(vm, closure.newCallFrame);
     1171#endif
    11181172
    11191173    // Execute the code:
     
    11261180        result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
    11271181#elif ENABLE(JIT)
    1128         result = closure.functionExecutable->generatedJITCodeForCall()->execute(&m_stack, closure.newCallFrame, &vm);
     1182        result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.newCallFrame, m_stack.getTopOfStack());
    11291183#endif // ENABLE(JIT)
    11301184    }
     
    11331187        profiler->didExecute(closure.oldCallFrame, closure.function);
    11341188
     1189#if ENABLE(LLINT_C_LOOP)
    11351190    m_stack.validateFence(closure.newCallFrame, "AFTER");
     1191#endif
    11361192    return checkedReturn(result);
    11371193}
    11381194
     1195#if ENABLE(LLINT_C_LOOP)
    11391196void Interpreter::endRepeatCall(CallFrameClosure& closure)
    11401197{
    11411198    m_stack.popFrame(closure.newCallFrame);
    11421199}
     1200#endif
    11431201
    11441202JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
     
    12041262    // Push the frame:
    12051263    ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
     1264#if ENABLE(LLINT_C_LOOP)
    12061265    CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
    12071266    if (UNLIKELY(!newCallFrame))
     
    12101269    // Set the arguments for the callee:
    12111270    newCallFrame->setThisValue(thisValue);
     1271#else
     1272    if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
     1273        return checkedReturn(throwStackOverflowError(callFrame));
     1274
     1275    ProtoCallFrame protoCallFrame;
     1276    protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
     1277#endif
    12121278
    12131279    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    12231289        result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
    12241290#elif ENABLE(JIT)
    1225         result = eval->generatedJITCode()->execute(&m_stack, newCallFrame, &vm);
     1291        result = eval->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    12261292#endif // ENABLE(JIT)
    12271293    }
     
    12301296        profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
    12311297
     1298#if ENABLE(LLINT_C_LOOP)
    12321299    m_stack.popFrame(newCallFrame);
     1300#endif
    12331301    return checkedReturn(result);
    12341302}
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r158586 r160094  
    6060    struct HandlerInfo;
    6161    struct Instruction;
    62    
     62    struct ProtoCallFrame;
     63
    6364    enum DebugHookID {
    6465        WillExecuteProgram,
     
    257258        enum ExecutionFlag { Normal, InitializeAndReturn };
    258259
     260#if !ENABLE(LLINT_C_LOOP)
     261        CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*);
     262#else
    259263        CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*);
    260264        void endRepeatCall(CallFrameClosure&);
     265#endif
    261266        JSValue execute(CallFrameClosure&);
    262267
  • trunk/Source/JavaScriptCore/interpreter/JSStack.h

    r159826 r160094  
    3636#include <wtf/VMTags.h>
    3737
     38#define ENABLE_DEBUG_JSSTACK 0
    3839#if !defined(NDEBUG) && !defined(ENABLE_DEBUG_JSSTACK)
    3940#define ENABLE_DEBUG_JSSTACK 1
     
    99100        Register* getStartOfFrame(CallFrame*);
    100101        Register* getTopOfStack();
     102
     103        bool entryCheck(class CodeBlock*, int);
    101104
    102105        CallFrame* pushFrame(CallFrame* callerFrame, class CodeBlock*,
  • trunk/Source/JavaScriptCore/interpreter/JSStackInlines.h

    r159721 r160094  
    5252}
    5353
    54 inline CallFrame* JSStack::pushFrame(CallFrame* callerFrame,
    55     class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
    56 {
    57     ASSERT(!!scope);
     54inline bool JSStack::entryCheck(class CodeBlock* codeBlock, int argsCount)
     55{
    5856    Register* oldEnd = getTopOfStack();
    5957
     
    7876    // Ensure that we have the needed stack capacity to push the new frame:
    7977    if (!grow(newEnd))
     78        return false;
     79
     80    return true;
     81}
     82
     83inline CallFrame* JSStack::pushFrame(CallFrame* callerFrame,
     84    class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
     85{
     86    ASSERT(!!scope);
     87    Register* oldEnd = getTopOfStack();
     88
     89    // Ensure that we have enough space for the parameters:
     90    size_t paddedArgsCount = argsCount;
     91    if (codeBlock) {
     92        size_t numParameters = codeBlock->numParameters();
     93        if (paddedArgsCount < numParameters)
     94            paddedArgsCount = numParameters;
     95    }
     96
     97    Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;
     98
     99#if ENABLE(DEBUG_JSSTACK)
     100    newCallFrameSlot -= JSStack::FenceSize;
     101#endif
     102
     103    Register* newEnd = newCallFrameSlot;
     104    if (!!codeBlock)
     105        newEnd += virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset();
     106
     107    // Ensure that we have the needed stack capacity to push the new frame:
     108    if (!grow(newEnd))
    80109        return 0;
    81110
    82     // Compute the address of the new VM sentinal frame for this invocation:
    83     CallFrame* newVMEntrySentinalFrame = CallFrame::create(newCallFrameSlot + paddedArgsCount + JSStack::CallFrameHeaderSize);
    84     ASSERT(!!newVMEntrySentinalFrame);
     111    // Compute the address of the new VM sentinel frame for this invocation:
     112    CallFrame* newVMEntrySentinelFrame = CallFrame::create(newCallFrameSlot + paddedArgsCount + JSStack::CallFrameHeaderSize);
     113    ASSERT(!!newVMEntrySentinelFrame);
    85114
    86115    // Compute the address of the new frame for this invocation:
     
    93122    callerFrame = m_topCallFrame;
    94123
    95     // Initialize the VM sentinal frame header:
    96     newVMEntrySentinalFrame->initializeVMEntrySentinelFrame(callerFrame);
     124    // Initialize the VM sentinel frame header:
     125    newVMEntrySentinelFrame->initializeVMEntrySentinelFrame(callerFrame);
    97126
    98127    // Initialize the callee frame header:
    99     newCallFrame->init(codeBlock, 0, scope, newVMEntrySentinalFrame, argsCount, callee);
     128    newCallFrame->init(codeBlock, 0, scope, newVMEntrySentinelFrame, argsCount, callee);
    100129
    101130    ASSERT(!!newCallFrame->scope());
     
    121150    validateFence(frame, __FUNCTION__, __LINE__);
    122151
    123     // Pop off the callee frame and the sentinal frame.
     152    // Pop off the callee frame and the sentinel frame.
    124153    CallFrame* callerFrame = frame->callerFrame()->vmEntrySentinelCallerFrame();
    125154
     
    184213//                     | *** the Fence ***                    |
    185214//                     |--------------------------------------|
    186 //                     | VM entry sentinal frame header       |
     215//                     | VM entry sentinel frame header       |
    187216//                     |--------------------------------------|
    188217//                     | Args of new frame                    |
  • trunk/Source/JavaScriptCore/jit/JITCode.cpp

    r159276 r160094  
    4343
    4444#if ENABLE(JIT)
    45 JSValue JITCode::execute(JSStack* stack, CallFrame* callFrame, VM* vm)
     45JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame, Register* topOfStack)
    4646{
    47     UNUSED_PARAM(stack);
     47    ASSERT(!vm->topCallFrame || ((Register*)(vm->topCallFrame) >= topOfStack));
    4848
    49     JSValue result = JSValue::decode(callToJavaScript(executableAddress(), callFrame));
     49    JSValue result = JSValue::decode(callToJavaScript(executableAddress(), &vm->topCallFrame, protoCallFrame, topOfStack));
    5050    return vm->exception() ? jsNull() : result;
    5151}
  • trunk/Source/JavaScriptCore/jit/JITCode.h

    r157044 r160094  
    5050class VM;
    5151class JSStack;
     52struct ProtoCallFrame;
    5253#endif
    5354
     
    178179    virtual FTL::ForOSREntryJITCode* ftlForOSREntry();
    179180   
    180     JSValue execute(JSStack*, CallFrame*, VM*);
     181    JSValue execute(VM*, ProtoCallFrame*, Register*);
    181182   
    182183    void* start() { return dataAddressAtOffset(0); }
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r159721 r160094  
    7777    VM* vm = codeBlock->vm();
    7878    CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel();
     79    if (!callerFrame)
     80        callerFrame = exec;
     81
    7982    NativeCallFrameTracer tracer(vm, callerFrame);
    8083
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r159276 r160094  
    3939#if OS(WINDOWS)
    4040class ExecState;
     41class Register;
     42struct ProtoCallFrame;
    4143
    4244extern "C" {
    43     EncodedJSValue callToJavaScript(void*, ExecState*);
     45    EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*, Register*);
    4446    void returnFromJavaScript();
     47    EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*, Register*);
    4548}
    4649#endif
  • trunk/Source/JavaScriptCore/jit/JITStubsMSVC64.asm

    r159376 r160094  
    3333
    3434callToJavaScript PROC
     35    ;; FIXME: This function has not been tested as the Win 64 port doesn't currently use the JIT.
     36    ;; It is believed to be an accurate adaptation of the assembly created by the llint stub of the
     37    ;; same name with changes for agrument register differences.
     38    int 3
    3539    mov r10, qword ptr[rsp]
    3640    push rbp
     
    5054    ; an additional 28h bytes.
    5155    sub rsp, 28h
    52     mov rbp, rdx
    53     mov r11, qword ptr[rbp] ; Put the previous frame pointer in the sentinel call frame above us
    54     mov qword ptr[r11], rax
    55     mov qword ptr[r11 + 8], r10
     56
     57    mov rbp, r9
     58    sub rbp, 40
     59    mov qword ptr[rbp + 40], 0
     60    mov qword ptr[rbp + 32], rdx
     61
     62    mov rax, qword ptr[rdx]
     63    mov qword ptr[rbp + 24], rax
     64    mov qword ptr[rbp + 16], 1
     65    mov qword ptr[rbp + 8], r10
     66    mov qword ptr[rbp], rax
     67    mov rax, rbp
     68
     69    mov ebx, dword ptr[r8 + 40]
     70    add rbx, 6
     71    sal rbx, 3
     72    sub rbp, rbx
     73    mov qword ptr[rbp], rax
     74
     75    mov rax, 5
     76
     77copyHeaderLoop:
     78    sub rax, 1
     79    mov r10, qword ptr[r8 + rax * 8]
     80    mov qword ptr[rbp + rax * 8 + 16], r10
     81    test rax, rax
     82    jnz copyHeaderLoop
     83
     84    mov ebx, dword ptr[r8 + 24]
     85    sub rbx, 1
     86    mov r10d, dword ptr[r8 + 40]
     87    sub r10, 1
     88    cmp rbx, r10
     89    je copyArgs
     90    mov rax, 0ah
     91
     92fillExtraArgsLoop:
     93    sub r10, 1
     94    mov qword ptr[rbp + r10 * 8 + 56], rax
     95    cmp rbx, r10
     96    jne fillExtraArgsLoop
     97
     98copyArgs:
     99    mov rax, qword ptr[r8 + 48]
     100
     101copyArgsLoop:
     102    test ebx, ebx
     103    jz copyArgsDone
     104    sub ebx, 1
     105    mov r10, qword ptr[rax + rbx * 8]
     106    mov qword ptr[rbp + rbx * 8 + 56], r10
     107    jmp copyArgsLoop
     108
     109copyArgsDone:
     110    mov qword ptr[rdx], rbp
    56111    mov r14, 0FFFF000000000000h
    57112    mov r15, 0FFFF000000000002h
    58113    call rcx
     114    cmp qword ptr[rbp + 16], 1
     115    je calleeFramePopped
     116    mov rbp, qword ptr[rbp]
     117
     118calleeFramePopped:
     119    mov rbx, qword ptr[rbp + 32] ; VM.topCallFrame
     120    mov r10, qword ptr[rbp + 24]
     121    mov qword ptr[rbx], r10
    59122    add rsp, 28h
    60123    pop rdi
     
    68131    ret
    69132callToJavaScript ENDP
     133
     134callToNativeFunction PROC
     135    ;; FIXME: This function has not been tested as the Win 64 port doesn't currently use the JIT.
     136    ;; It is believed to be an accurate adaptation of the assembly created by the llint stub of the
     137    ;; same name with changes for agrument register differences.
     138    int 3
     139    mov r10, qword ptr[rsp]
     140    push rbp
     141    mov rax, rbp ; Save previous frame pointer
     142    mov rbp, rsp
     143    push r12
     144    push r13
     145    push r14
     146    push r15
     147    push rbx
     148    push rsi
     149    push rdi
     150
     151    ; JIT operations can use up to 6 args (4 in registers and 2 on the stack).
     152    ; In addition, X86_64 ABI specifies that the worse case stack alignment
     153    ; requirement is 32 bytes. Based on these factors, we need to pad the stack
     154    ; an additional 28h bytes.
     155    sub rsp, 28h
     156
     157    mov rbp, r9
     158    sub rbp, 40
     159    mov qword ptr[rbp + 40], 0
     160    mov qword ptr[rbp + 32], rdx
     161
     162    mov rax, qword ptr[rdx]
     163    mov qword ptr[rbp + 24], rax
     164    mov qword ptr[rbp + 16], 1
     165    mov qword ptr[rbp + 8], r10
     166    mov qword ptr[rbp], rax
     167    mov rax, rbp
     168
     169    mov ebx, dword ptr[r8 + 40]
     170    add rbx, 6
     171    sal rbx, 3
     172    sub rbp, rbx
     173    mov qword ptr[rbp], rax
     174
     175    mov rax, 5
     176
     177copyHeaderLoop:
     178    sub rax, 1
     179    mov r10, qword ptr[r8 + rax * 8]
     180    mov qword ptr[rbp + rax * 8 + 16], r10
     181    test rax, rax
     182    jnz copyHeaderLoop
     183
     184    mov ebx, dword ptr[r8 + 24]
     185    sub rbx, 1
     186    mov r10d, dword ptr[r8 + 40]
     187    sub r10, 1
     188    cmp rbx, r10
     189    je copyArgs
     190    mov rax, 0ah
     191
     192fillExtraArgsLoop:
     193    sub r10, 1
     194    mov qword ptr[rbp + r10 * 8 + 56], rax
     195    cmp rbx, r10
     196    jne fillExtraArgsLoop
     197
     198copyArgs:
     199    mov rax, qword ptr[r8 + 48]
     200
     201copyArgsLoop:
     202    test rbx, rbx
     203    jz copyArgsDone
     204    sub rbx, 1
     205    mov r10, qword ptr[rax + rbx * 8]
     206    mov qword ptr[rbp + rbx * 8 + 56], r10
     207    jmp copyArgsLoop
     208
     209copyArgsDone:
     210    mov qword ptr[rdx], rbp
     211    mov r14, 0FFFF000000000000h
     212    mov r15, 0FFFF000000000002h
     213
     214    mov rax, rcx
     215    mov rcx, rbp
     216    call rax
     217
     218    cmp qword ptr[rbp + 16], 1
     219    je calleeFramePopped
     220    mov rbp, qword ptr[rbp]
     221
     222calleeFramePopped:
     223    mov rbx, qword ptr[rbp + 32] ; VM.topCallFrame
     224    mov r10, qword ptr[rbp + 24]
     225    mov qword ptr[rbx], r10
     226    add rsp, 28h
     227    pop rdi
     228    pop rsi
     229    pop rbx
     230    pop r15
     231    pop r14
     232    pop r13
     233    pop r12
     234    pop rbp
     235    ret
     236callToNativeFunction ENDP
    70237
    71238returnFromJavaScript PROC
  • trunk/Source/JavaScriptCore/jit/JITStubsX86.h

    r159346 r160094  
    207207    // FIXME: Since Windows doesn't use the LLInt, we have inline stubs here.
    208208    // Until the LLInt is changed to support Windows, these stub needs to be updated.
    209     __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState*)
     209    __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState**, ProtoCallFrame*, Register*)
    210210    {
    211211        __asm {
     
    218218            push ebx;
    219219            sub esp, 0x1c;
    220             mov ebp, [esp + 0x34];
    221             mov ebx, [ebp];
    222             mov [ebx], eax;
    223             mov 4[ebx], edx
    224             call [esp + 0x30];
     220            mov ecx, dword ptr[esp + 0x34];
     221            mov esi, dword ptr[esp + 0x38];
     222            mov ebp, dword ptr[esp + 0x3c];
     223            sub ebp, 0x20;
     224            mov dword ptr[ebp + 0x24], 0;
     225            mov dword ptr[ebp + 0x20], 0;
     226            mov dword ptr[ebp + 0x1c], 0;
     227            mov dword ptr[ebp + 0x18], ecx;
     228            mov ebx, [ecx];
     229            mov dword ptr[ebp + 0x14], 0;
     230            mov dword ptr[ebp + 0x10], ebx;
     231            mov dword ptr[ebp + 0xc], 0;
     232            mov dword ptr[ebp + 0x8], 1;
     233            mov dword ptr[ebp + 0x4], edx;
     234            mov dword ptr[ebp], eax;
     235            mov eax, ebp;
     236
     237            mov edx, dword ptr[esi + 0x28];
     238            add edx, 5;
     239            sal edx, 3;
     240            sub ebp, edx;
     241            mov dword ptr[ebp], eax;
     242
     243            mov eax, 5;
     244
     245        copyHeaderLoop:
     246            sub eax, 1;
     247            mov ecx, dword ptr[esi + eax * 8];
     248            mov dword ptr 8[ebp + eax * 8], ecx;
     249            mov ecx, dword ptr 4[esi + eax * 8];
     250            mov dword ptr 12[ebp + eax * 8], ecx;
     251            test eax, eax;
     252            jnz copyHeaderLoop;
     253
     254            mov edx, dword ptr[esi + 0x18];
     255            sub edx, 1;
     256            mov ecx, dword ptr[esi + 0x28];
     257            sub ecx, 1;
     258
     259            cmp edx, ecx;
     260            je copyArgs;
     261
     262            xor eax, eax;
     263            mov ebx, -4;
     264
     265        fillExtraArgsLoop:
     266            sub ecx, 1;
     267            mov dword ptr 0x30[ebp + ecx * 8], eax;           
     268            mov dword ptr 0x34[ebp + ecx * 8], ebx;
     269            cmp edx, ecx;
     270            jne fillExtraArgsLoop;
     271
     272        copyArgs:
     273            mov eax, dword ptr[esi + 0x2c];
     274
     275        copyArgsLoop:
     276            test edx, edx;
     277            jz copyArgsDone;
     278            sub edx, 1;
     279            mov ecx, dword ptr 0[eax + edx * 8];
     280            mov ebx, dword ptr 4[eax + edx * 8];
     281            mov dword ptr 0x30[ebp + edx * 8], ecx;
     282            mov dword ptr 0x34[ebp + edx * 8], ebx;
     283            jmp copyArgsLoop;
     284
     285        copyArgsDone:
     286            mov ecx, dword ptr[esp + 0x34];
     287            mov dword ptr[ecx], ebp;
     288
     289            call dword ptr[esp + 0x30];
     290
     291            cmp dword ptr[ebp + 8], 1;
     292            je calleeFramePopped;
     293            mov ebp, dword ptr[ebp];
     294
     295        calleeFramePopped:
     296            mov ecx, dword ptr[ebp + 0x18];
     297            mov ebx, dword ptr[ebp + 0x10];
     298            mov dword ptr[ecx], ebx;
     299
    225300            add esp, 0x1c;
    226301            pop ebx;
     
    243318        }
    244319    }
     320
     321    __declspec(naked) EncodedJSValue callToNativeFunction(void* code, ExecState**, ProtoCallFrame*, Register*)
     322    {
     323        __asm {
     324            mov edx, [esp]
     325            push ebp;
     326            mov eax, ebp;
     327            mov ebp, esp;
     328            push esi;
     329            push edi;
     330            push ebx;
     331            sub esp, 0x1c;
     332            mov ecx, [esp + 0x34];
     333            mov esi, [esp + 0x38];
     334            mov ebp, [esp + 0x3c];
     335            sub ebp, 0x20;
     336            mov dword ptr[ebp + 0x24], 0;
     337            mov dword ptr[ebp + 0x20], 0;
     338            mov dword ptr[ebp + 0x1c], 0;
     339            mov dword ptr[ebp + 0x18], ecx;
     340            mov ebx, [ecx];
     341            mov dword ptr[ebp + 0x14], 0;
     342            mov dword ptr[ebp + 0x10], ebx;
     343            mov dword ptr[ebp + 0xc], 0;
     344            mov dword ptr[ebp + 0x8], 1;
     345            mov dword ptr[ebp + 0x4], edx;
     346            mov dword ptr[ebp], eax;
     347            mov eax, ebp;
     348
     349            mov edx, dword ptr[esi + 0x28];
     350            add edx, 5;
     351            sal edx, 3;
     352            sub ebp, edx;
     353            mov dword ptr[ebp], eax;
     354
     355            mov eax, 5;
     356
     357        copyHeaderLoop:
     358            sub eax, 1;
     359            mov ecx, dword ptr[esi + eax * 8];
     360            mov dword ptr 8[ebp + eax * 8], ecx;
     361            mov ecx, dword ptr 4[esi + eax * 8];
     362            mov dword ptr 12[ebp + eax * 8], ecx;
     363            test eax, eax;
     364            jnz copyHeaderLoop;
     365
     366            mov edx, dword ptr[esi + 0x18];
     367            sub edx, 1;
     368            mov ecx, dword ptr[esi + 0x28];
     369            sub ecx, 1;
     370
     371            cmp edx, ecx;
     372            je copyArgs;
     373
     374            xor eax, eax;
     375            mov ebx, -4;
     376
     377        fillExtraArgsLoop:
     378            sub ecx, 1;
     379            mov dword ptr 0x30[ebp + ecx * 8], eax;           
     380            mov dword ptr 0x34[ebp + ecx * 8], ebx;
     381            cmp edx, ecx;
     382            jne fillExtraArgsLoop;
     383
     384        copyArgs:
     385            mov eax, dword ptr[esi + 0x2c];
     386
     387        copyArgsLoop:
     388            test edx, edx;
     389            jz copyArgsDone;
     390            sub edx, 1;
     391            mov ecx, dword ptr 0[eax + edx * 8];
     392            mov ebx, dword ptr 4[eax + edx * 8];
     393            mov dword ptr 0x30[ebp + edx * 8], ecx;
     394            mov dword ptr 0x34[ebp + edx * 8], ebx;
     395            jmp copyArgsLoop;
     396
     397        copyArgsDone:
     398            mov ecx, dword ptr[esp + 0x34];
     399            mov dword ptr[ecx], ebp;
     400
     401            mov edi, dword ptr[esp + 0x30];
     402            mov dword ptr[esp + 0x30], ebp;
     403            mov ecx, ebp;
     404            call edi;
     405
     406            cmp dword ptr[ebp + 8], 1;
     407            je calleeFramePopped;
     408            mov ebp, dword ptr[ebp];
     409
     410        calleeFramePopped:
     411            mov ecx, dword ptr[ebp + 0x18];
     412            mov ebx, dword ptr[ebp + 0x10];
     413            mov dword ptr[ecx], ebx;
     414
     415            add esp, 0x1c;
     416            pop ebx;
     417            pop edi;
     418            pop esi;
     419            pop ebp;
     420            ret;
     421        }
     422    }
    245423}
    246424
  • trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp

    r157746 r160094  
    4747#include "LLIntOfflineAsmConfig.h"
    4848#include "MarkedSpace.h"
    49 
     49#include "ProtoCallFrame.h"
    5050#include "Structure.h"
    5151#include "StructureChain.h"
  • trunk/Source/JavaScriptCore/llint/LLIntThunks.h

    r159276 r160094  
    3636
    3737class ExecState;
     38class Register;
    3839class VM;
     40struct ProtoCallFrame;
    3941
    4042extern "C" {
    41     EncodedJSValue callToJavaScript(void*, ExecState*);
     43    EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*, Register*);
    4244    void returnFromJavaScript();
     45    EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*, Register*);
    4346}
    4447
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r160082 r160094  
    424424if C_LOOP
    425425else
    426 # stub to call into JavaScript
    427 # EncodedJSValue callToJavaScript(void* code, Register* topOfStack)
    428 # Note, if this stub or one of it's related macros is changed, make the
     426# stub to call into JavaScript or Native functions
     427# EncodedJSValue callToJavaScript(void* code, ExecState** vm, ProtoCallFrame* protoFrame, Register* topOfStack)
     428# EncodedJSValue callToNativeFunction(void* code, ExecState** vm, ProtoCallFrame* protoFrame, Register* topOfStack)
     429# Note, if these stubs or one of their related macros are changed, make the
    429430# equivalent changes in jit/JITStubsX86.h and/or jit/JITStubsMSVC64.asm
    430431_callToJavaScript:
    431     doCallToJavaScript()
     432    doCallToJavaScript(makeJavaScriptCall, doReturnFromJavaScript)
     433
     434_callToNativeFunction:
     435    doCallToJavaScript(makeHostFunctionCall, doReturnFromHostFunction)
    432436end
    433437
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r159943 r160094  
    171171end
    172172
    173 macro doCallToJavaScript()
     173macro doCallToJavaScript(makeCall, doReturn)
    174174    if X86
     175        const entry = t5
     176        const vmTopCallFrame = t2
     177        const protoCallFrame = t4
     178
    175179        const extraStackSpace = 28
    176180        const previousCFR = t0
    177181        const previousPC = t1
    178         const entry = t5
    179         const newCallFrame = t4
     182        const temp1 = t0 # Same as previousCFR
     183        const temp2 = t1 # Same as previousPC
     184        const temp3 = t2 # same as vmTopCallFrame
     185        const temp4 = t3
    180186    elsif ARM or ARMv7_TRADITIONAL
     187        const entry = a0
     188        const vmTopCallFrame = a1
     189        const protoCallFrame = a2
     190        const topOfStack = a3
     191
    181192        const extraStackSpace = 16
    182         const previousCFR = t3 
     193        const previousCFR = t3
    183194        const previousPC = lr
     195        const temp1 = t3 # Same as previousCFR
     196        const temp2 = a3 # Same as topOfStack
     197        const temp3 = t4
     198        const temp4 = t5
     199    elsif ARMv7
    184200        const entry = a0
    185         const newCallFrame = a1
    186     elsif ARMv7
     201        const vmTopCallFrame = a1
     202        const protoCallFrame = a2
     203        const topOfStack = a3
     204
    187205        const extraStackSpace = 28
    188         const previousCFR = t3 
     206        const previousCFR = t3
    189207        const previousPC = lr
     208        const temp1 = t3 # Same as previousCFR
     209        const temp2 = a3 # Same as topOfStack
     210        const temp3 = t4
     211        const temp4 = t5
     212    elsif MIPS
    190213        const entry = a0
    191         const newCallFrame = a1
    192     elsif MIPS
     214        const vmTopCallFrame = a1
     215        const protoCallFrame = a2
     216        const topOfStack = a3
     217
    193218        const extraStackSpace = 36
    194219        const previousCFR = t2
    195220        const previousPC = lr
     221        const temp1 = t3
     222        const temp2 = t4
     223        const temp3 = t5
     224        const temp4 = t6
     225    elsif SH4
    196226        const entry = a0
    197         const newCallFrame = a1
    198     elsif SH4
     227        const vmTopCallFrame = a1
     228        const protoCallFrame = a2
     229        const topOfStack = a3
     230
    199231        const extraStackSpace = 20
    200         const previousCFR = t3 
     232        const previousCFR = t3
    201233        const previousPC = lr
    202         const entry = a0
    203         const newCallFrame = a1
     234        const temp1 = t3 # Same as previousCFR
     235        const temp2 = a3 # Same as topOfStack
     236        const temp3 = t4
     237        const temp4 = t5
    204238    end
    205239
     
    211245    if X86
    212246        loadp extraStackSpace+20[sp], entry
    213         loadp extraStackSpace+24[sp], newCallFrame
     247        loadp extraStackSpace+24[sp], vmTopCallFrame
     248        loadp extraStackSpace+28[sp], protoCallFrame
     249        loadp extraStackSpace+32[sp], cfr
    214250    else
    215251        move cfr, previousCFR
     252        move topOfStack, cfr
    216253    end
    217254
    218     move newCallFrame, cfr
    219     loadp [cfr], newCallFrame
    220     storep previousCFR, [newCallFrame]
    221     storep previousPC, 4[newCallFrame]
     255    subp (CallFrameHeaderSlots-1)*8, cfr
     256    storep 0, ArgumentCount+4[cfr]
     257    storep 0, ArgumentCount[cfr]
     258    storep 0, Callee+4[cfr]
     259    storep vmTopCallFrame, Callee[cfr]
     260    loadp [vmTopCallFrame], temp4
     261    storep 0, ScopeChain+4[cfr]
     262    storep temp4, ScopeChain[cfr]
     263    storep 0, CodeBlock+4[cfr]
     264    storep 1, CodeBlock[cfr]
     265    storep previousPC, ReturnPC[cfr]
     266    storep previousCFR, CallerFrame[cfr]
     267    move cfr, temp1
     268
     269    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
     270    addp CallFrameHeaderSlots, temp2, temp2
     271    lshiftp 3, temp2
     272    subp temp2, cfr
     273    storep temp1, CallerFrame[cfr]
     274
     275    move 5, temp1
     276
     277.copyHeaderLoop:
     278    subi 1, temp1
     279    loadp [protoCallFrame, temp1, 8], temp3
     280    storep temp3, CodeBlock[cfr, temp1, 8]
     281    loadp 4[protoCallFrame, temp1, 8], temp3
     282    storep temp3, CodeBlock+4[cfr, temp1, 8]
     283    btinz temp1, .copyHeaderLoop
     284
     285    loadi ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], temp2
     286    subi 1, temp2
     287    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp3
     288    subi 1, temp3
     289
     290    bieq temp2, temp3, .copyArgs
     291    move 0, temp1
     292    move UndefinedTag, temp4
     293.fillExtraArgsLoop:
     294    subi 1, temp3
     295    storep temp1, ThisArgumentOffset+8+PayloadOffset[cfr, temp3, 8]
     296    storep temp4, ThisArgumentOffset+8+TagOffset[cfr, temp3, 8]
     297    bineq temp2, temp3, .fillExtraArgsLoop
     298
     299.copyArgs:
     300    loadp ProtoCallFrame::args[protoCallFrame], temp1
     301
     302.copyArgsLoop:
     303    btiz temp2, .copyArgsDone
     304    subi 1, temp2
     305    loadp PayloadOffset[temp1, temp2, 8], temp3
     306    loadp TagOffset[temp1, temp2, 8], temp4
     307    storep temp3, ThisArgumentOffset+8+PayloadOffset[cfr, temp2, 8]
     308    storep temp4, ThisArgumentOffset+8+TagOffset[cfr, temp2, 8]
     309    jmp .copyArgsLoop
     310
     311.copyArgsDone:
     312    if X86
     313        loadp extraStackSpace+24[sp], vmTopCallFrame
     314    end
     315    storep cfr, [vmTopCallFrame]
     316
     317    makeCall(entry, temp1)
     318
     319    bpeq CodeBlock[cfr], 1, .calleeFramePopped
     320    loadp CallerFrame[cfr], cfr
     321
     322.calleeFramePopped:
     323    loadp Callee[cfr], temp3 # VM.topCallFrame
     324    loadp ScopeChain[cfr], temp4
     325    storep temp4, [temp3]
     326
     327    doReturn(extraStackSpace)
     328end
     329
     330macro makeJavaScriptCall(entry, temp)
    222331    call entry
    223 
     332end
     333
     334macro makeHostFunctionCall(entry, temp)
     335    move entry, temp
     336    if X86
     337        # Put cfr on stack as arg0, also put it in ecx for "fastcall" targets
     338        poke cfr, 0
     339        move cfr, t2
     340    else
     341        move cfr, a0
     342    end
     343    call temp
     344end
     345
     346macro doReturnFromJavaScript(extraStackSpace)
    224347_returnFromJavaScript:
     348    functionEpilogue(extraStackSpace)
     349    ret
     350end
     351
     352macro doReturnFromHostFunction(extraStackSpace)
    225353    functionEpilogue(extraStackSpace)
    226354    ret
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r159943 r160094  
    114114end
    115115
    116 macro doCallToJavaScript()
     116macro doCallToJavaScript(makeCall, doReturn)
    117117    if X86_64
     118        const entry = t5
     119        const vmTopCallFrame = t4
     120        const protoCallFrame = t1
     121        const topOfStack = t2
     122
    118123        const extraStackSpace = 8
    119124        const previousCFR = t0
    120125        const previousPC = t6
    121         const entry = t5
    122         const newCallFrame = t4
     126        const temp1 = t0
     127        const temp2 = t3
     128        const temp3 = t6
    123129    elsif ARM64
     130        const entry = a0
     131        const vmTopCallFrame = a1
     132        const protoCallFrame = a2
     133        const topOfStack = a3
     134
    124135        const extraStackSpace = 0
    125136        const previousCFR = t4
    126137        const previousPC = lr
    127         const entry = a0
    128         const newCallFrame = a1
    129     elsif C_LOOP
    130         const extraStackSpace = 0
    131         const previousCFR = t4 
    132         const previousPC = lr
    133         const entry = a0
    134         const newCallFrame = a1
     138        const temp1 = t3
     139        const temp2 = t5
     140        const temp3 = t6
    135141    end
    136142
     
    141147    functionPrologue(extraStackSpace)
    142148
    143     move newCallFrame, cfr
    144     loadp [cfr], newCallFrame
    145     storep previousCFR, [newCallFrame]
    146     storep previousPC, 8[newCallFrame]
     149    move topOfStack, cfr
     150    subp (CallFrameHeaderSlots-1)*8, cfr
     151    storep 0, ArgumentCount[cfr]
     152    storep vmTopCallFrame, Callee[cfr]
     153    loadp [vmTopCallFrame], temp1
     154    storep temp1, ScopeChain[cfr]
     155    storep 1, CodeBlock[cfr]
     156    storep previousPC, ReturnPC[cfr]
     157    storep previousCFR, CallerFrame[cfr]
     158    move cfr, temp1
     159
     160    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
     161    addp CallFrameHeaderSlots, temp2, temp2
     162    lshiftp 3, temp2
     163    subp temp2, cfr
     164    storep temp1, CallerFrame[cfr]
     165
     166    move 5, temp1
     167
     168.copyHeaderLoop:
     169    subi 1, temp1
     170    loadp [protoCallFrame, temp1, 8], temp3
     171    storep temp3, CodeBlock[cfr, temp1, 8]
     172    btinz temp1, .copyHeaderLoop
     173
     174    loadi ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], temp2
     175    subi 1, temp2
     176    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp3
     177    subi 1, temp3
     178
     179    bieq temp2, temp3, .copyArgs
     180    move ValueUndefined, temp1
     181.fillExtraArgsLoop:
     182    subi 1, temp3
     183    storep temp1, ThisArgumentOffset+8[cfr, temp3, 8]
     184    bineq temp2, temp3, .fillExtraArgsLoop
     185
     186.copyArgs:
     187    loadp ProtoCallFrame::args[protoCallFrame], temp1
     188
     189.copyArgsLoop:
     190    btiz temp2, .copyArgsDone
     191    subi 1, temp2
     192    loadp [temp1, temp2, 8], temp3
     193    storep temp3, ThisArgumentOffset+8[cfr, temp2, 8]
     194    jmp .copyArgsLoop
     195
     196.copyArgsDone:
     197    storep cfr, [vmTopCallFrame]
     198
    147199    move 0xffff000000000000, csr1
    148200    addp 2, csr1, csr2
     201
     202    makeCall(entry, temp1)
     203
     204    bpeq CodeBlock[cfr], 1, .calleeFramePopped
     205    loadp CallerFrame[cfr], cfr
     206
     207.calleeFramePopped:
     208    loadp Callee[cfr], temp2 # VM.topCallFrame
     209    loadp ScopeChain[cfr], temp3
     210    storep temp3, [temp2]
     211
     212    doReturn(extraStackSpace)
     213end
     214
     215macro makeJavaScriptCall(entry, temp)
    149216    call entry
    150 
     217end
     218
     219macro makeHostFunctionCall(entry, temp)
     220    move entry, temp
     221    if X86_64
     222        move cfr, t5
     223    elsif ARM64 or C_LOOP
     224        move cfr, a0
     225    end
     226    call temp
     227end
     228
     229macro doReturnFromJavaScript(extraStackSpace)
    151230_returnFromJavaScript:
     231    functionEpilogue(extraStackSpace)
     232    ret
     233end
     234
     235macro doReturnFromHostFunction(extraStackSpace)
    152236    functionEpilogue(extraStackSpace)
    153237    ret
  • trunk/Source/JavaScriptCore/runtime/ArgList.h

    r155711 r160094  
    140140
    141141class ArgList {
     142    friend class Interpreter;
    142143    friend class JIT;
    143144public:
     
    173174
    174175private:
     176    JSValue* data() const { return m_args; }
     177
    175178    JSValue* m_args;
    176179    int m_argCount;
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r156214 r160094  
    13211321            m_cachedCall->setArgument(0, va);
    13221322            m_cachedCall->setArgument(1, vb);
     1323#if ENABLE(LLINT_C_LOOP)
    13231324            compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec));
     1325#else
     1326            compareResult = m_cachedCall->call().toNumber(m_exec);
     1327#endif
    13241328        } else {
    13251329            MarkedArgumentBuffer arguments;
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r156620 r160094  
    505505                cachedCall.setThis(jsUndefined());
    506506                JSValue jsResult = cachedCall.call();
     507#if ENABLE(LLINT_C_LOOP)
    507508                replacements.append(jsResult.toString(cachedCall.newCallFrame(exec))->value(exec));
     509#else
     510                replacements.append(jsResult.toString(exec)->value(exec));
     511#endif
    508512                if (exec->hadException())
    509513                    break;
     
    544548                cachedCall.setThis(jsUndefined());
    545549                JSValue jsResult = cachedCall.call();
     550#if ENABLE(LLINT_C_LOOP)
    546551                replacements.append(jsResult.toString(cachedCall.newCallFrame(exec))->value(exec));
     552#else
     553                replacements.append(jsResult.toString(exec)->value(exec));
     554#endif
    547555                if (exec->hadException())
    548556                    break;
Note: See TracChangeset for help on using the changeset viewer.