Changeset 163700 in webkit


Ignore:
Timestamp:
Feb 8, 2014 12:27:13 AM (10 years ago)
Author:
mark.lam@apple.com
Message:

JSLock should not "restore" VM stack values if it did not re-grab locks.
<https://webkit.org/b/128447>

Reviewed by Geoffrey Garen.

In the existing code, if DropAllLocks is instantiate with DontAlwaysDropLocks
in a thread that does not own the JSLock, then a bug will manifest where:

  1. The DropAllLocks constructor will save the VM's stackPointerAtEntry, lastStackTop, and reservedZoneSize even though it will not drop the JSLock.
  2. The DropAllLocks destructor will restore those 3 values to the VM even though the JSLock will not grab its internal lock.

The former only causes busy work but does not impact correctness. The latter
however, will corrupt those 3 VM values which belong to the thread that
actually owns the JSLock.

The fix is to only save the values when the JSLock will actually drop its
internal lock, and only restore the values if it did re-grab the internal lock.

  • runtime/JSLock.cpp:

(JSC::JSLock::dropAllLocks):
(JSC::JSLock::dropAllLocksUnconditionally):
(JSC::JSLock::grabAllLocks):
(JSC::JSLock::DropAllLocks::DropAllLocks):

  • Moved the saving of VM stack values to dropAllLocks() and dropAllLocksUnconditionally().

(JSC::JSLock::DropAllLocks::~DropAllLocks):

  • Moved the restoring of VM stack values to grabAllLocks().
Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r163695 r163700  
     12014-02-07  Mark Lam  <mark.lam@apple.com>
     2
     3        JSLock should not "restore" VM stack values if it did not re-grab locks.
     4        <https://webkit.org/b/128447>
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        In the existing code, if DropAllLocks is instantiate with DontAlwaysDropLocks
     9        in a thread that does not own the JSLock, then a bug will manifest where:
     10
     11        1. The DropAllLocks constructor will save the VM's stackPointerAtEntry,
     12           lastStackTop, and reservedZoneSize even though it will not drop the JSLock.
     13        2. The DropAllLocks destructor will restore those 3 values to the VM even
     14           though the JSLock will not grab its internal lock.
     15
     16        The former only causes busy work but does not impact correctness. The latter
     17        however, will corrupt those 3 VM values which belong to the thread that
     18        actually owns the JSLock.
     19
     20        The fix is to only save the values when the JSLock will actually drop its
     21        internal lock, and only restore the values if it did re-grab the internal lock.
     22
     23        * runtime/JSLock.cpp:
     24        (JSC::JSLock::dropAllLocks):
     25        (JSC::JSLock::dropAllLocksUnconditionally):
     26        (JSC::JSLock::grabAllLocks):
     27        (JSC::JSLock::DropAllLocks::DropAllLocks):
     28        - Moved the saving of VM stack values to dropAllLocks() and
     29          dropAllLocksUnconditionally().
     30        (JSC::JSLock::DropAllLocks::~DropAllLocks):
     31        - Moved the restoring of VM stack values to grabAllLocks().
     32
    1332014-02-07  Filip Pizlo  <fpizlo@apple.com>
    234
  • trunk/Source/JavaScriptCore/runtime/JSLock.cpp

    r163685 r163700  
    222222        return 0;
    223223
     224    WTFThreadData& threadData = wtfThreadData();
     225    threadData.setSavedStackPointerAtVMEntry(m_vm->stackPointerAtVMEntry);
     226    threadData.setSavedLastStackTop(m_vm->lastStackTop());
     227    threadData.setSavedReservedZoneSize(m_vm->reservedZoneSize());
     228
    224229    // m_lockDropDepth is only incremented if any locks were dropped.
    225230    ++m_lockDropDepth;
     
    242247        return 0;
    243248
     249    WTFThreadData& threadData = wtfThreadData();
     250    threadData.setSavedStackPointerAtVMEntry(m_vm->stackPointerAtVMEntry);
     251    threadData.setSavedLastStackTop(m_vm->lastStackTop());
     252    threadData.setSavedReservedZoneSize(m_vm->reservedZoneSize());
     253
    244254    // m_lockDropDepth is only incremented if any locks were dropped.
    245255    ++m_lockDropDepth;
     
    277287    m_lockCount = lockCount;
    278288    --m_lockDropDepth;
     289
     290    WTFThreadData& threadData = wtfThreadData();
     291    m_vm->stackPointerAtVMEntry = threadData.savedStackPointerAtVMEntry();
     292    m_vm->setLastStackTop(threadData.savedLastStackTop());
     293    m_vm->updateStackLimitWithReservedZoneSize(threadData.savedReservedZoneSize());
    279294}
    280295
     
    287302    SpinLock& spinLock = m_vm->apiLock().m_spinLock;
    288303    SpinLockHolder holder(&spinLock);
    289 
    290     WTFThreadData& threadData = wtfThreadData();
    291    
    292     threadData.setSavedStackPointerAtVMEntry(m_vm->stackPointerAtVMEntry);
    293     threadData.setSavedLastStackTop(m_vm->lastStackTop());
    294     threadData.setSavedReservedZoneSize(m_vm->reservedZoneSize());
    295304
    296305    if (alwaysDropLocks)
     
    309318    SpinLockHolder holder(&spinLock);
    310319
    311     WTFThreadData& threadData = wtfThreadData();
    312    
    313     threadData.setSavedStackPointerAtVMEntry(m_vm->stackPointerAtVMEntry);
    314     threadData.setSavedLastStackTop(m_vm->lastStackTop());
    315     threadData.setSavedReservedZoneSize(m_vm->reservedZoneSize());
    316 
    317320    if (alwaysDropLocks)
    318321        m_lockCount = m_vm->apiLock().dropAllLocksUnconditionally(spinLock);
     
    328331    SpinLockHolder holder(&spinLock);
    329332    m_vm->apiLock().grabAllLocks(m_lockCount, spinLock);
    330 
    331     WTFThreadData& threadData = wtfThreadData();
    332 
    333     m_vm->stackPointerAtVMEntry = threadData.savedStackPointerAtVMEntry();
    334     m_vm->setLastStackTop(threadData.savedLastStackTop());
    335     m_vm->updateStackLimitWithReservedZoneSize(threadData.savedReservedZoneSize());
    336333}
    337334
Note: See TracChangeset for help on using the changeset viewer.