Ignore:
Timestamp:
Dec 4, 2013, 8:40:17 AM (12 years ago)
Author:
[email protected]
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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.