⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 159706 in webkit


Ignore:
Timestamp:
Nov 22, 2013, 12:31:38 PM (13 years ago)
Author:
mark.lam@apple.com
Message:

Ensure that arity fixups honor stack alignment requirements.
https://bugs.webkit.org/show_bug.cgi?id=124756.

Reviewed by Geoffrey Garen.

The LLINT and all the JITs rely on CommonSlowPaths::arityCheckFor() to
compute the arg count adjustment for the arity fixup. We take advantage
of this choke point and introduce the stack alignment padding there in
the guise of additional args.

The only cost of this approach is that the padding will also be
initialized to undefined values as if they were args. Since arity fixups
are considered a slow path that is rarely taken, this cost is not a
concern.

  • runtime/CommonSlowPaths.h:

(JSC::CommonSlowPaths::arityCheckFor):

  • runtime/VM.h:

(JSC::VM::isSafeToRecurse):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r159705 r159706  
     12013-11-22  Mark Lam  <mark.lam@apple.com>
     2
     3        Ensure that arity fixups honor stack alignment requirements.
     4        https://bugs.webkit.org/show_bug.cgi?id=124756.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        The LLINT and all the JITs rely on CommonSlowPaths::arityCheckFor() to
     9        compute the arg count adjustment for the arity fixup. We take advantage
     10        of this choke point and introduce the stack alignment padding there in
     11        the guise of additional args.
     12
     13        The only cost of this approach is that the padding will also be
     14        initialized to undefined values as if they were args. Since arity fixups
     15        are considered a slow path that is rarely taken, this cost is not a
     16        concern.
     17
     18        * runtime/CommonSlowPaths.h:
     19        (JSC::CommonSlowPaths::arityCheckFor):
     20        * runtime/VM.h:
     21        (JSC::VM::isSafeToRecurse):
     22
    1232013-11-21  Filip Pizlo  <fpizlo@apple.com>
    224
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r159605 r159706  
    3232#include "JSStackInlines.h"
    3333#include "NameInstance.h"
     34#include "StackAlignment.h"
     35#include "VM.h"
    3436#include <wtf/Platform.h>
     37#include <wtf/StdLibExtras.h>
    3538
    3639#if ENABLE(JIT) || ENABLE(LLINT)
     
    5457    int argumentCountIncludingThis = exec->argumentCountIncludingThis();
    5558   
    56     // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
    57     if (!stack->grow(exec->registers() - newCodeBlock->numParameters() + virtualRegisterForLocal(newCodeBlock->m_numCalleeRegisters).offset()))
     59    ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
     60    int missingArgumentCount = newCodeBlock->numParameters() - argumentCountIncludingThis;
     61    int paddedMissingArgumentCount = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), missingArgumentCount);
     62
     63#if USE(SEPARATE_C_AND_JS_STACK)
     64    if (!stack->grow(exec->registers() - paddedMissingArgumentCount))
    5865        return -1;
    59    
    60     ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
    61    
    62     // Too few arguments, return the number of missing arguments so the caller can
    63     // grow the frame in place and fill in undefined values for the missing args.
    64     return(newCodeBlock->numParameters() - argumentCountIncludingThis);
     66#else
     67    UNUSED_PARAM(stack);
     68    if (!exec->vm().isSafeToRecurse(paddedMissingArgumentCount * sizeof(Register)))
     69        return -1;
     70#endif // USE(SEPARATE_C_AND_JS_STACK)
     71
     72    return paddedMissingArgumentCount;
    6573}
    6674
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r159605 r159706  
    370370        void* stackLimit() { return m_stackLimit; }
    371371        void setStackLimit(void* limit) { m_stackLimit = limit; }
    372         bool isSafeToRecurse() const
     372        bool isSafeToRecurse(size_t neededStackInBytes = 0) const
    373373        {
    374374            ASSERT(wtfThreadData().stack().isGrowingDownward());
    375             void* curr;
    376             return &curr >= m_stackLimit;
     375            int8_t* curr = reinterpret_cast<int8_t*>(&curr);
     376            int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
     377            return curr >= limit && static_cast<size_t>(curr - limit) >= neededStackInBytes;
    377378        }
    378379
Note: See TracChangeset for help on using the changeset viewer.