Changeset 190215 in webkit


Ignore:
Timestamp:
Sep 24, 2015, 12:23:58 PM (10 years ago)
Author:
fpizlo@apple.com
Message:

PolymorphicAccess should remember that it checked an ObjectPropertyCondition with a check on some structure
https://bugs.webkit.org/show_bug.cgi?id=149514

Reviewed by Oliver Hunt.

When we checked an ObjectPropertyCondition using an explicit structure check, we would forget to
note the structure in any weak reference table and we would attempt to regenerate the condition
check even if the condition became invalid.

We need to account for this better and we need to prune AccessCases that have an invalid condition
set. This change does both.

  • bytecode/PolymorphicAccess.cpp:

(JSC::AccessGenerationState::addWatchpoint):
(JSC::AccessCase::alternateBase):
(JSC::AccessCase::couldStillSucceed):
(JSC::AccessCase::canReplace):
(JSC::AccessCase::generate):
(JSC::PolymorphicAccess::regenerateWithCases):
(JSC::PolymorphicAccess::visitWeak):
(JSC::PolymorphicAccess::regenerate):

  • bytecode/PolymorphicAccess.h:

(JSC::AccessCase::callLinkInfo):

  • tests/stress/make-dictionary-repatch.js: Added. This used to crash on a release assert. If we removed the release assert, this would return bad results.
Location:
trunk/Source/JavaScriptCore
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r190213 r190215  
     12015-09-23  Filip Pizlo  <fpizlo@apple.com>
     2
     3        PolymorphicAccess should remember that it checked an ObjectPropertyCondition with a check on some structure
     4        https://bugs.webkit.org/show_bug.cgi?id=149514
     5
     6        Reviewed by Oliver Hunt.
     7
     8        When we checked an ObjectPropertyCondition using an explicit structure check, we would forget to
     9        note the structure in any weak reference table and we would attempt to regenerate the condition
     10        check even if the condition became invalid.
     11
     12        We need to account for this better and we need to prune AccessCases that have an invalid condition
     13        set. This change does both.
     14
     15        * bytecode/PolymorphicAccess.cpp:
     16        (JSC::AccessGenerationState::addWatchpoint):
     17        (JSC::AccessCase::alternateBase):
     18        (JSC::AccessCase::couldStillSucceed):
     19        (JSC::AccessCase::canReplace):
     20        (JSC::AccessCase::generate):
     21        (JSC::PolymorphicAccess::regenerateWithCases):
     22        (JSC::PolymorphicAccess::visitWeak):
     23        (JSC::PolymorphicAccess::regenerate):
     24        * bytecode/PolymorphicAccess.h:
     25        (JSC::AccessCase::callLinkInfo):
     26        * tests/stress/make-dictionary-repatch.js: Added. This used to crash on a release assert. If we removed the release assert, this would return bad results.
     27
    1282015-09-24  Mark Lam  <mark.lam@apple.com>
    229
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp

    r190129 r190215  
    6262    const Identifier* ident;
    6363    std::unique_ptr<WatchpointsOnStructureStubInfo> watchpoints;
     64    Vector<WriteBarrier<JSCell>> weakReferences;
    6465
    6566    Watchpoint* addWatchpoint(const ObjectPropertyCondition& condition = ObjectPropertyCondition())
     
    252253}
    253254
     255bool AccessCase::couldStillSucceed() const
     256{
     257    return m_conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint();
     258}
     259
    254260bool AccessCase::canReplace(const AccessCase& other)
    255261{
     
    376382    CCallHelpers& jit = *state.jit;
    377383    VM& vm = *jit.vm();
     384    CodeBlock* codeBlock = jit.codeBlock();
    378385    StructureStubInfo& stubInfo = *state.stubInfo;
    379386    const Identifier& ident = *state.ident;
     
    399406        }
    400407
    401         RELEASE_ASSERT(condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(structure));
     408        if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(structure)) {
     409            dataLog("This condition is no longer met: ", condition, "\n");
     410            RELEASE_ASSERT_NOT_REACHED();
     411        }
     412
     413        // We will emit code that has a weak reference that isn't otherwise listed anywhere.
     414        state.weakReferences.append(WriteBarrier<JSCell>(vm, codeBlock->ownerExecutable(), structure));
     415       
    402416        jit.move(CCallHelpers::TrustedImmPtr(condition.object()), scratchGPR);
    403417        state.failAndRepatch.append(
     
    978992    ListType newCases;
    979993    for (auto& oldCase : m_list) {
     994        // Ignore old cases that cannot possibly succeed anymore.
     995        if (!oldCase->couldStillSucceed())
     996            continue;
     997
     998        // Figure out if this is replaced by any new cases.
    980999        bool found = false;
    9811000        for (auto& caseToAdd : casesToAdd) {
     
    9851004            }
    9861005        }
    987         if (!found)
    988             newCases.append(oldCase->clone());
     1006        if (found)
     1007            continue;
     1008       
     1009        newCases.append(oldCase->clone());
    9891010    }
    9901011    for (auto& caseToAdd : casesToAdd)
     
    10221043        if (!at(i).visitWeak(vm))
    10231044            return false;
     1045    }
     1046    if (Vector<WriteBarrier<JSCell>>* weakReferences = m_weakReferences.get()) {
     1047        for (WriteBarrier<JSCell>& weakReference : *weakReferences) {
     1048            if (!Heap::isMarked(weakReference.get()))
     1049                return false;
     1050        }
    10241051    }
    10251052    return true;
     
    11461173    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock->ownerExecutable(), doesCalls);
    11471174    m_watchpoints = WTF::move(state.watchpoints);
     1175    if (!state.weakReferences.isEmpty())
     1176        m_weakReferences = std::make_unique<Vector<WriteBarrier<JSCell>>>(WTF::move(state.weakReferences));
    11481177    if (verbose)
    11491178        dataLog("Returning: ", code.code(), "\n");
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h

    r189586 r190215  
    207207    }
    208208
     209    // Is it still possible for this case to ever be taken?
     210    bool couldStillSucceed() const;
     211
    209212    // If this method returns true, then it's a good idea to remove 'other' from the access once 'this'
    210213    // is added. This method assumes that in case of contradictions, 'this' represents a newer, and so
     
    302305    RefPtr<JITStubRoutine> m_stubRoutine;
    303306    std::unique_ptr<WatchpointsOnStructureStubInfo> m_watchpoints;
     307    std::unique_ptr<Vector<WriteBarrier<JSCell>>> m_weakReferences;
    304308};
    305309
Note: See TracChangeset for help on using the changeset viewer.