Changeset 243626 in webkit


Ignore:
Timestamp:
Mar 28, 2019 3:05:34 PM (5 years ago)
Author:
Tadeu Zagallo
Message:

CodeBlock::jettison() should disallow repatching its own calls
https://bugs.webkit.org/show_bug.cgi?id=196359
<rdar://problem/48973663>

Reviewed by Saam Barati.

JSTests:

  • stress/call-link-info-osrexit-repatch.js: Added.

(foo):

Source/JavaScriptCore:

CodeBlock::jettison() calls CommonData::invalidate, which replaces the hlt
instruction with the jump to OSR exit. However, if the hlt was immediately
followed by a call to the CodeBlock being jettisoned, we would write over the
OSR exit address while unlinking all the incoming CallLinkInfos later in
CodeBlock::jettison().

Change it so that we set a flag, clearedByJettison, in all the CallLinkInfos
owned by the CodeBlock being jettisoned. If the flag is set, we will avoid
repatching the call during unlinking. This is safe because this call will never
be reachable again after the CodeBlock is jettisoned.

  • bytecode/CallLinkInfo.cpp:

(JSC::CallLinkInfo::CallLinkInfo):
(JSC::CallLinkInfo::setCallee):
(JSC::CallLinkInfo::clearCallee):
(JSC::CallLinkInfo::setCodeBlock):
(JSC::CallLinkInfo::clearCodeBlock):

  • bytecode/CallLinkInfo.h:

(JSC::CallLinkInfo::clearedByJettison):
(JSC::CallLinkInfo::setClearedByJettison):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::jettison):

  • jit/Repatch.cpp:

(JSC::revertCall):

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r243624 r243626  
     12019-03-28  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        CodeBlock::jettison() should disallow repatching its own calls
     4        https://bugs.webkit.org/show_bug.cgi?id=196359
     5        <rdar://problem/48973663>
     6
     7        Reviewed by Saam Barati.
     8
     9        * stress/call-link-info-osrexit-repatch.js: Added.
     10        (foo):
     11
    1122019-03-28  Yusuke Suzuki  <ysuzuki@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r243617 r243626  
     12019-03-28  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        CodeBlock::jettison() should disallow repatching its own calls
     4        https://bugs.webkit.org/show_bug.cgi?id=196359
     5        <rdar://problem/48973663>
     6
     7        Reviewed by Saam Barati.
     8
     9        CodeBlock::jettison() calls CommonData::invalidate, which replaces the `hlt`
     10        instruction with the jump to OSR exit. However, if the `hlt` was immediately
     11        followed by a call to the CodeBlock being jettisoned, we would write over the
     12        OSR exit address while unlinking all the incoming CallLinkInfos later in
     13        CodeBlock::jettison().
     14
     15        Change it so that we set a flag, `clearedByJettison`, in all the CallLinkInfos
     16        owned by the CodeBlock being jettisoned. If the flag is set, we will avoid
     17        repatching the call during unlinking. This is safe because this call will never
     18        be reachable again after the CodeBlock is jettisoned.
     19
     20        * bytecode/CallLinkInfo.cpp:
     21        (JSC::CallLinkInfo::CallLinkInfo):
     22        (JSC::CallLinkInfo::setCallee):
     23        (JSC::CallLinkInfo::clearCallee):
     24        (JSC::CallLinkInfo::setCodeBlock):
     25        (JSC::CallLinkInfo::clearCodeBlock):
     26        * bytecode/CallLinkInfo.h:
     27        (JSC::CallLinkInfo::clearedByJettison):
     28        (JSC::CallLinkInfo::setClearedByJettison):
     29        * bytecode/CodeBlock.cpp:
     30        (JSC::CodeBlock::jettison):
     31        * jit/Repatch.cpp:
     32        (JSC::revertCall):
     33
    1342019-03-27  Yusuke Suzuki  <ysuzuki@apple.com>
    235
  • trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp

    r243467 r243626  
    6262    , m_clearedByVirtual(false)
    6363    , m_allowStubs(true)
    64     , m_isLinked(false)
     64    , m_clearedByJettison(false)
    6565    , m_callType(None)
    6666    , m_calleeGPR(255)
     
    128128    MacroAssembler::repatchPointer(hotPathBegin(), callee);
    129129    m_calleeOrCodeBlock.set(vm, owner, callee);
    130     m_isLinked = true;
    131130}
    132131
     
    136135    MacroAssembler::repatchPointer(hotPathBegin(), nullptr);
    137136    m_calleeOrCodeBlock.clear();
    138     m_isLinked = false;
    139137}
    140138
     
    149147    RELEASE_ASSERT(isDirect());
    150148    m_calleeOrCodeBlock.setMayBeNull(vm, owner, codeBlock);
    151     m_isLinked = true;
    152149}
    153150
     
    156153    RELEASE_ASSERT(isDirect());
    157154    m_calleeOrCodeBlock.clear();
    158     m_isLinked = false;
    159155}
    160156
  • trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h

    r234086 r243626  
    271271    }
    272272
     273    bool clearedByJettison()
     274    {
     275        return m_clearedByJettison;
     276    }
     277
    273278    void setClearedByVirtual()
    274279    {
    275280        m_clearedByVirtual = true;
     281    }
     282
     283    void setClearedByJettison()
     284    {
     285        m_clearedByJettison = true;
    276286    }
    277287   
     
    351361    bool m_clearedByVirtual : 1;
    352362    bool m_allowStubs : 1;
    353     bool m_isLinked : 1;
     363    bool m_clearedByJettison : 1;
    354364    unsigned m_callType : 4; // CallType
    355365    unsigned m_calleeGPR : 8;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r243467 r243626  
    20502050        return;
    20512051
     2052#if ENABLE(JIT)
     2053    {
     2054        ConcurrentJSLocker locker(m_lock);
     2055        if (JITData* jitData = m_jitData.get()) {
     2056            for (CallLinkInfo* callLinkInfo : jitData->m_callLinkInfos)
     2057                callLinkInfo->setClearedByJettison();
     2058        }
     2059    }
     2060#endif
     2061
    20522062    // This accomplishes (2).
    20532063    ownerExecutable()->installCode(vm, alternative(), codeType(), specializationKind());
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r242252 r243626  
    896896static void revertCall(VM* vm, CallLinkInfo& callLinkInfo, MacroAssemblerCodeRef<JITStubRoutinePtrTag> codeRef)
    897897{
    898     if (callLinkInfo.isDirect()) {
    899         callLinkInfo.clearCodeBlock();
    900         if (callLinkInfo.callType() == CallLinkInfo::DirectTailCall)
    901             MacroAssembler::repatchJump(callLinkInfo.patchableJump(), callLinkInfo.slowPathStart());
    902         else
    903             MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), callLinkInfo.slowPathStart());
    904     } else {
    905         MacroAssembler::revertJumpReplacementToBranchPtrWithPatch(
    906             MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
    907             static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0);
    908         linkSlowFor(vm, callLinkInfo, codeRef);
    909         callLinkInfo.clearCallee();
     898    if (!callLinkInfo.clearedByJettison()) {
     899        if (callLinkInfo.isDirect()) {
     900            callLinkInfo.clearCodeBlock();
     901            if (callLinkInfo.callType() == CallLinkInfo::DirectTailCall)
     902                MacroAssembler::repatchJump(callLinkInfo.patchableJump(), callLinkInfo.slowPathStart());
     903            else
     904                MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), callLinkInfo.slowPathStart());
     905        } else {
     906            MacroAssembler::revertJumpReplacementToBranchPtrWithPatch(
     907                MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
     908                static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0);
     909            linkSlowFor(vm, callLinkInfo, codeRef);
     910            callLinkInfo.clearCallee();
     911        }
    910912    }
    911913    callLinkInfo.clearSeen();
Note: See TracChangeset for help on using the changeset viewer.