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

Changeset 259646 in webkit


Ignore:
Timestamp:
Apr 7, 2020, 11:04:57 AM (6 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] ScopedArgumentsTable should handle OOM in tolerant manner
https://bugs.webkit.org/show_bug.cgi?id=210126

Reviewed by Mark Lam.

JSTests:

  • stress/scoped-arguments-table-should-be-tolerant-for-oom.js: Added.

(canThrow):
(bar):
(get bar):
(foo):
(i.canThrow):

Source/JavaScriptCore:

This patch makes ScopedArgumentsTable allocations OOM tolerant to throw OOM error when allocation fails.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):

  • runtime/CachedTypes.cpp:

(JSC::CachedScopedArgumentsTable::decode const):

  • runtime/ScopedArguments.cpp:

(JSC::ScopedArguments::unmapArgument):

  • runtime/ScopedArgumentsTable.cpp:

(JSC::ScopedArgumentsTable::tryClone):
(JSC::ScopedArgumentsTable::trySetLength):
(JSC::ScopedArgumentsTable::trySet):
(JSC::ScopedArgumentsTable::clone): Deleted.
(JSC::ScopedArgumentsTable::setLength): Deleted.
(JSC::ScopedArgumentsTable::set): Deleted.

  • runtime/ScopedArgumentsTable.h:
  • runtime/SymbolTable.h:
Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r259638 r259646  
     12020-04-07  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] ScopedArgumentsTable should handle OOM in tolerant manner
     4        https://bugs.webkit.org/show_bug.cgi?id=210126
     5
     6        Reviewed by Mark Lam.
     7
     8        * stress/scoped-arguments-table-should-be-tolerant-for-oom.js: Added.
     9        (canThrow):
     10        (bar):
     11        (get bar):
     12        (foo):
     13        (i.canThrow):
     14
    1152020-04-07  Yusuke Suzuki  <ysuzuki@apple.com>
    216
  • trunk/Source/JavaScriptCore/ChangeLog

    r259645 r259646  
     12020-04-07  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] ScopedArgumentsTable should handle OOM in tolerant manner
     4        https://bugs.webkit.org/show_bug.cgi?id=210126
     5
     6        Reviewed by Mark Lam.
     7
     8        This patch makes ScopedArgumentsTable allocations OOM tolerant to throw OOM error when allocation fails.
     9
     10        * bytecompiler/BytecodeGenerator.cpp:
     11        (JSC::BytecodeGenerator::BytecodeGenerator):
     12        * runtime/CachedTypes.cpp:
     13        (JSC::CachedScopedArgumentsTable::decode const):
     14        * runtime/ScopedArguments.cpp:
     15        (JSC::ScopedArguments::unmapArgument):
     16        * runtime/ScopedArgumentsTable.cpp:
     17        (JSC::ScopedArgumentsTable::tryClone):
     18        (JSC::ScopedArgumentsTable::trySetLength):
     19        (JSC::ScopedArgumentsTable::trySet):
     20        (JSC::ScopedArgumentsTable::clone): Deleted.
     21        (JSC::ScopedArgumentsTable::setLength): Deleted.
     22        (JSC::ScopedArgumentsTable::set): Deleted.
     23        * runtime/ScopedArgumentsTable.h:
     24        * runtime/SymbolTable.h:
     25
    1262020-04-07  Yusuke Suzuki  <ysuzuki@apple.com>
    227
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r258071 r259646  
    506506            for (unsigned i = 0; i < parameters.size(); ++i) {
    507507                ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
    508                 functionSymbolTable->setArgumentOffset(vm, i, offset);
     508                bool success = functionSymbolTable->trySetArgumentOffset(vm, i, offset);
     509                if (UNLIKELY(!success)) {
     510                    m_outOfMemoryDuringConstruction = true;
     511                    return;
     512                }
    509513                if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first)) {
    510514                    VarOffset varOffset(offset);
  • trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp

    r257719 r259646  
    11221122    ScopedArgumentsTable* decode(Decoder& decoder) const
    11231123    {
    1124         ScopedArgumentsTable* scopedArgumentsTable = ScopedArgumentsTable::create(decoder.vm(), m_length);
     1124        ScopedArgumentsTable* scopedArgumentsTable = ScopedArgumentsTable::tryCreate(decoder.vm(), m_length);
     1125        RELEASE_ASSERT(scopedArgumentsTable); // We crash here. This is unlikely to continue execution if we hit this condition when decoding UnlinkedCodeBlock.
    11251126        m_arguments.decode(decoder, scopedArgumentsTable->m_arguments.get(m_length), m_length);
    11261127        return scopedArgumentsTable;
  • trunk/Source/JavaScriptCore/runtime/ScopedArguments.cpp

    r256087 r259646  
    144144{
    145145    VM& vm = globalObject->vm();
     146    auto scope = DECLARE_THROW_SCOPE(vm);
    146147    ASSERT_WITH_SECURITY_IMPLICATION(i < m_totalLength);
    147148    unsigned namedLength = m_table->length();
    148     if (i < namedLength)
    149         m_table.set(vm, this, m_table->set(vm, i, ScopeOffset()));
    150     else
     149    if (i < namedLength) {
     150        auto* maybeCloned = m_table->trySet(vm, i, ScopeOffset());
     151        if (UNLIKELY(!maybeCloned)) {
     152            throwOutOfMemoryError(globalObject, scope);
     153            return;
     154        }
     155        m_table.set(vm, this, maybeCloned);
     156    } else
    151157        storage()[i - namedLength].clear();
    152158}
  • trunk/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp

    r257907 r259646  
    5757}
    5858
    59 ScopedArgumentsTable* ScopedArgumentsTable::create(VM& vm, uint32_t length)
    60 {
    61     ScopedArgumentsTable* result = create(vm);
    62     result->m_length = length;
    63     result->m_arguments = ArgumentsPtr::create(length);
    64     return result;
    65 }
    66 
    6759ScopedArgumentsTable* ScopedArgumentsTable::tryCreate(VM& vm, uint32_t length)
    6860{
     
    8072}
    8173
    82 ScopedArgumentsTable* ScopedArgumentsTable::clone(VM& vm)
     74ScopedArgumentsTable* ScopedArgumentsTable::tryClone(VM& vm)
    8375{
    84     ScopedArgumentsTable* result = create(vm, m_length);
     76    ScopedArgumentsTable* result = tryCreate(vm, m_length);
     77    if (UNLIKELY(!result))
     78        return nullptr;
    8579    for (unsigned i = m_length; i--;)
    8680        result->at(i) = this->at(i);
     
    8882}
    8983
    90 ScopedArgumentsTable* ScopedArgumentsTable::setLength(VM& vm, uint32_t newLength)
     84ScopedArgumentsTable* ScopedArgumentsTable::trySetLength(VM& vm, uint32_t newLength)
    9185{
    9286    if (LIKELY(!m_locked)) {
    93         ArgumentsPtr newArguments = ArgumentsPtr::create(newLength, newLength);
     87        ArgumentsPtr newArguments = ArgumentsPtr::tryCreate(newLength, newLength);
     88        if (UNLIKELY(!newArguments))
     89            return nullptr;
    9490        for (unsigned i = std::min(m_length, newLength); i--;)
    9591            newArguments.at(i, newLength) = this->at(i);
     
    9995    }
    10096   
    101     ScopedArgumentsTable* result = create(vm, newLength);
     97    ScopedArgumentsTable* result = tryCreate(vm, newLength);
     98    if (UNLIKELY(!result))
     99        return nullptr;
    102100    for (unsigned i = std::min(m_length, newLength); i--;)
    103101        result->at(i) = this->at(i);
     
    107105static_assert(std::is_trivially_destructible<ScopeOffset>::value, "");
    108106
    109 ScopedArgumentsTable* ScopedArgumentsTable::set(VM& vm, uint32_t i, ScopeOffset value)
     107ScopedArgumentsTable* ScopedArgumentsTable::trySet(VM& vm, uint32_t i, ScopeOffset value)
    110108{
    111109    ScopedArgumentsTable* result;
    112     if (UNLIKELY(m_locked))
    113         result = clone(vm);
    114     else
     110    if (UNLIKELY(m_locked)) {
     111        result = tryClone(vm);
     112        if (UNLIKELY(!result))
     113            return nullptr;
     114    } else
    115115        result = this;
    116116    result->at(i) = value;
  • trunk/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h

    r257907 r259646  
    6060public:
    6161    static ScopedArgumentsTable* create(VM&);
    62     static ScopedArgumentsTable* create(VM&, uint32_t length);
    6362    static ScopedArgumentsTable* tryCreate(VM&, uint32_t length);
    6463
    6564    static void destroy(JSCell*);
    6665
    67     ScopedArgumentsTable* clone(VM&);
    68    
    6966    uint32_t length() const { return m_length; }
    70     ScopedArgumentsTable* setLength(VM&, uint32_t newLength);
     67    ScopedArgumentsTable* trySetLength(VM&, uint32_t newLength);
    7168   
    7269    ScopeOffset get(uint32_t i) const { return at(i); }
     
    7774    }
    7875   
    79     ScopedArgumentsTable* set(VM&, uint32_t index, ScopeOffset);
     76    ScopedArgumentsTable* trySet(VM&, uint32_t index, ScopeOffset);
    8077   
    8178    DECLARE_INFO;
     
    8986
    9087private:
     88    ScopedArgumentsTable* tryClone(VM&);
     89
    9190    ScopeOffset& at(uint32_t i) const
    9291    {
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r257907 r259646  
    643643                return false;
    644644            m_arguments.set(vm, this, table);
    645         } else
    646             m_arguments.set(vm, this, m_arguments->setLength(vm, length));
     645        } else {
     646            ScopedArgumentsTable* table = m_arguments->trySetLength(vm, length);
     647            if (UNLIKELY(!table))
     648                return false;
     649            m_arguments.set(vm, this, table);
     650        }
    647651        return true;
    648652    }
     
    654658    }
    655659   
    656     void setArgumentOffset(VM& vm, uint32_t i, ScopeOffset offset)
     660    bool trySetArgumentOffset(VM& vm, uint32_t i, ScopeOffset offset)
    657661    {
    658662        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
    659         m_arguments.set(vm, this, m_arguments->set(vm, i, offset));
     663        auto* maybeCloned = m_arguments->trySet(vm, i, offset);
     664        if (!maybeCloned)
     665            return false;
     666        m_arguments.set(vm, this, maybeCloned);
     667        return true;
    660668    }
    661669   
Note: See TracChangeset for help on using the changeset viewer.