Changeset 160960 in webkit


Ignore:
Timestamp:
Dec 20, 2013, 11:11:59 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

CStack: Introduce JSStack::ensureCapacityFor().
https://bugs.webkit.org/show_bug.cgi?id=126109.

Not yet reviewed.

Client code should use JSStack::ensureCapacityFor() when checking for
available stack space for pushing JS frames or making arity adjustments.
JSStack::ensureCapacityFor() works for both cases of the JS stack on the
C stack or as a sperate stack.

JSStack::grow() is now private, and is only used by the C Loop LLINT.

Also made some other JSStack methods private as they are not needed
outside of the JSSTack class.

  • dfg/DFGOSREntry.cpp:

(JSC::DFG::prepareOSREntry):

  • ftl/FTLOSREntry.cpp:

(JSC::FTL::prepareOSREntry):

  • interpreter/Interpreter.cpp:

(JSC::sizeFrameForVarargs):

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

(JSC::JSStack::ensureCapacityFor):
(JSC::JSStack::topOfStackForCapacityCheck):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:

(JSC::CommonSlowPaths::arityCheckFor):

Location:
branches/jsCStack/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/jsCStack/Source/JavaScriptCore/ChangeLog

    r160958 r160960  
     12013-12-20  Mark Lam  <mark.lam@apple.com>
     2
     3        CStack: Introduce JSStack::ensureCapacityFor().
     4        https://bugs.webkit.org/show_bug.cgi?id=126109.
     5
     6        Not yet reviewed.
     7
     8        Client code should use JSStack::ensureCapacityFor() when checking for
     9        available stack space for pushing JS frames or making arity adjustments.
     10        JSStack::ensureCapacityFor() works for both cases of the JS stack on the
     11        C stack or as a sperate stack.
     12
     13        JSStack::grow() is now private, and is only used by the C Loop LLINT.
     14
     15        Also made some other JSStack methods private as they are not needed
     16        outside of the JSSTack class.
     17
     18        * dfg/DFGOSREntry.cpp:
     19        (JSC::DFG::prepareOSREntry):
     20        * ftl/FTLOSREntry.cpp:
     21        (JSC::FTL::prepareOSREntry):
     22        * interpreter/Interpreter.cpp:
     23        (JSC::sizeFrameForVarargs):
     24        * interpreter/JSStack.h:
     25        * interpreter/JSStackInlines.h:
     26        (JSC::JSStack::ensureCapacityFor):
     27        (JSC::JSStack::topOfStackForCapacityCheck):
     28        * llint/LLIntSlowPaths.cpp:
     29        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     30        * runtime/CommonSlowPaths.h:
     31        (JSC::CommonSlowPaths::arityCheckFor):
     32
    1332013-12-20  Filip Pizlo  <fpizlo@apple.com>
    234
  • branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSREntry.cpp

    r160694 r160960  
    189189   
    190190    unsigned frameSize = jitCode->common.requiredRegisterCountForExecutionAndExit();
    191     if (!vm->interpreter->stack().grow(&exec->registers()[virtualRegisterForLocal(frameSize).offset()])) {
     191    if (!vm->interpreter->stack().ensureCapacityFor(&exec->registers()[virtualRegisterForLocal(frameSize - 1).offset()])) {
    192192        if (Options::verboseOSR())
    193193            dataLogF("    OSR failed because stack growth failed.\n");
  • branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSREntry.cpp

    r160893 r160960  
    8181   
    8282    int stackFrameSize = entryCode->common.requiredRegisterCountForExecutionAndExit();
    83     if (!vm.interpreter->stack().grow(&exec->registers()[virtualRegisterForLocal(stackFrameSize).offset()])) {
     83    if (!vm.interpreter->stack().ensureCapacityFor(&exec->registers()[virtualRegisterForLocal(stackFrameSize - 1).offset()])) {
    8484        if (Options::verboseOSR())
    8585            dataLog("    OSR failed because stack growth failed.\n");
  • branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r160947 r160960  
    161161        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
    162162        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    163         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->grow(newCallFrame->registers())) {
     163        if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
    164164            callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
    165165            return 0;
     
    172172        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
    173173        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    174         if (!stack->grow(newCallFrame->registers())) {
     174        if (!stack->ensureCapacityFor(newCallFrame->registers())) {
    175175            callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
    176176            return 0;
     
    189189        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
    190190        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    191         if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
     191        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
    192192            callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
    193193            return 0;
     
    201201        unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
    202202        CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    203         if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
     203        if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
    204204            callFrame->vm().throwException(callFrame, createStackOverflowError(callFrame));
    205205            return 0;
     
    212212    unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
    213213    CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
    214     if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
     214    if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
    215215        callFrame->vm().throwException(callFrame,  createStackOverflowError(callFrame));
    216216        return 0;
  • branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h

    r160947 r160960  
    8282        ~JSStack();
    8383       
     84        bool ensureCapacityFor(Register* newTopOfStack);
     85
    8486        void gatherConservativeRoots(ConservativeRoots&);
    8587        void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&);
     
    9395        size_t size() const { return highAddress() - lowAddress(); }
    9496
    95         bool grow(Register* topOfStack);
    96        
    9797        static size_t committedByteCount();
    9898        static void initializeThreading();
    9999
    100         Register* topOfFrameFor(CallFrame*);
    101100        Register* startOfFrameFor(CallFrame*);
    102         Register* topOfStack();
    103101
    104102        CallFrame* pushFrame(class CodeBlock*, JSScope*, int argsCount, JSObject* callee);
     
    121119
    122120    private:
     121
     122        inline Register* topOfFrameFor(CallFrame*);
     123        inline Register* topOfStack();
     124        inline Register* topOfStackForCapacityCheck();
     125
    123126        Register* lowAddress() const
    124127        {
     
    144147#endif
    145148
     149        bool grow(Register* topOfStack);
    146150        bool growSlowCase(Register*);
    147151        void shrink(Register*);
  • branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h

    r160947 r160960  
    3434namespace JSC {
    3535
     36inline bool JSStack::ensureCapacityFor(Register* newTopOfStack)
     37{
     38#if ENABLE(LLINT_C_LOOP)
     39    return grow(newTopOfStack);
     40#else
     41    ASSERT(wtfThreadData().stack().isGrowingDownward());
     42    Register* topOfStack = topOfStackForCapacityCheck();
     43    if (newTopOfStack > topOfStack)
     44        return true;
     45    size_t neededCapacity = (topOfStack - newTopOfStack) * sizeof(Register);
     46    return m_vm.isSafeToRecurse(neededCapacity);
     47#endif
     48}
     49
     50inline Register* JSStack::topOfStackForCapacityCheck()
     51{
     52#if !ENABLE(LLINT_C_LOOP)
     53    // We're trying to get an estimate of the top of the stack for the purpose
     54    // of a capacity check. If m_topCallFrame is 0, then we can't calculate an
     55    // accurate top of stack value. Just use the current stack position as an
     56    // estimate for the top of the stack from where JS code will start executing.
     57    // This is conservative, but it will be safe.
     58    if (!m_topCallFrame) {
     59        Register* p = reinterpret_cast<Register*>(&p);
     60        return p;
     61    }
     62#endif
     63    return topOfStack() + 1;
     64}
     65
    3666inline Register* JSStack::topOfFrameFor(CallFrame* frame)
    3767{
  • branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r160947 r160960  
    442442    dataLogF("Current end is at %p.\n", exec->vm().interpreter->stack().end());
    443443#endif
    444     ASSERT(!exec->vm().interpreter->stack().containsAddress(&exec->registers()[virtualRegisterForLocal(exec->codeBlock()->m_numCalleeRegisters).offset()]));
    445     if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[virtualRegisterForLocal(exec->codeBlock()->m_numCalleeRegisters).offset()]))) {
     444
     445    // For JIT enabled builds which uses the C stack, the stack is not growable.
     446    // Hence, if we get here, then we know a stack overflow is imminent. So, just
     447    // throw the StackOverflowError unconditionally.
     448#if ENABLE(LLINT_C_LOOP)
     449    ASSERT(!exec->vm().interpreter->stack().containsAddress(exec->topOfFrame()));
     450    if (UNLIKELY(!vm.interpreter->stack().ensureCapacityFor(exec->topOfFrame())))
     451#endif
     452    {
    446453        exec = exec->callerFrame();
    447454        CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
  • branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r160936 r160960  
    6868    int paddedStackSpace = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), neededStackSpace);
    6969
    70 #if ENABLE(LLINT_CLOOP)
    71     if (!stack->grow(exec->registers() - passedStackSpace))
     70    if (!stack->ensureCapacityFor(exec->registers() - paddedStackSpace))
    7271        return -1;
    73 #else
    74     UNUSED_PARAM(stack);
    75     if (!exec->vm().isSafeToRecurse(paddedStackSpace * sizeof(Register)))
    76         return -1;
    77 #endif // ENABLE(LLINT_CLOOP)
    78 
    7972    return paddedStackSpace / stackAlignmentRegisters();
    8073}
Note: See TracChangeset for help on using the changeset viewer.