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

Changeset 280849 in webkit


Ignore:
Timestamp:
Aug 10, 2021, 10:08:20 AM (5 years ago)
Author:
Russell Epstein
Message:

Cherry-pick r280507. rdar://problem/79730568

Improve OSR entry into Wasm loops with arguments
https://bugs.webkit.org/show_bug.cgi?id=228595

Reviewed by Yusuke Suzuki.

JSTests:

Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
100k iterations was not enough to reliably complete an OSR entry.

  • wasm/stress/osr-entry-with-loop-arguments.js: Added. (async test):

Source/JavaScriptCore:

This patch has two parts:

  • improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
  • improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks. Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
  • b3/B3Validate.cpp:
  • wasm/WasmAirIRGenerator.cpp: (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck): (JSC::Wasm::AirIRGenerator::addLoop):
  • wasm/WasmB3IRGenerator.cpp: (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck): (JSC::Wasm::B3IRGenerator::addLoop):
  • wasm/WasmLLIntGenerator.cpp: (JSC::Wasm::LLIntGenerator::addLoop):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280507 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-611.3.10.0-branch
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-611.3.10.0-branch/JSTests/ChangeLog

    r280847 r280849  
     12021-08-10  Russell Epstein  <repstein@apple.com>
     2
     3        Cherry-pick r280507. rdar://problem/79730568
     4
     5    Improve OSR entry into Wasm loops with arguments
     6    https://bugs.webkit.org/show_bug.cgi?id=228595
     7   
     8    Reviewed by Yusuke Suzuki.
     9   
     10    JSTests:
     11   
     12    Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
     13    100k iterations was not enough to reliably complete an OSR entry.
     14   
     15    * wasm/stress/osr-entry-with-loop-arguments.js: Added.
     16    (async test):
     17   
     18    Source/JavaScriptCore:
     19   
     20    This patch has two parts:
     21    - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
     22    - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
     23      Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
     24   
     25    * b3/B3Validate.cpp:
     26    * wasm/WasmAirIRGenerator.cpp:
     27    (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
     28    (JSC::Wasm::AirIRGenerator::addLoop):
     29    * wasm/WasmB3IRGenerator.cpp:
     30    (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
     31    (JSC::Wasm::B3IRGenerator::addLoop):
     32    * wasm/WasmLLIntGenerator.cpp:
     33    (JSC::Wasm::LLIntGenerator::addLoop):
     34   
     35   
     36    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     37
     38    2021-07-30  Robin Morisset  <rmorisset@apple.com>
     39
     40            Improve OSR entry into Wasm loops with arguments
     41            https://bugs.webkit.org/show_bug.cgi?id=228595
     42
     43            Reviewed by Yusuke Suzuki.
     44
     45            Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
     46            100k iterations was not enough to reliably complete an OSR entry.
     47
     48            * wasm/stress/osr-entry-with-loop-arguments.js: Added.
     49            (async test):
     50
    1512021-08-10  Russell Epstein  <repstein@apple.com>
    252
  • branches/safari-611.3.10.0-branch/Source/JavaScriptCore/ChangeLog

    r280847 r280849  
     12021-08-10  Russell Epstein  <repstein@apple.com>
     2
     3        Cherry-pick r280507. rdar://problem/79730568
     4
     5    Improve OSR entry into Wasm loops with arguments
     6    https://bugs.webkit.org/show_bug.cgi?id=228595
     7   
     8    Reviewed by Yusuke Suzuki.
     9   
     10    JSTests:
     11   
     12    Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
     13    100k iterations was not enough to reliably complete an OSR entry.
     14   
     15    * wasm/stress/osr-entry-with-loop-arguments.js: Added.
     16    (async test):
     17   
     18    Source/JavaScriptCore:
     19   
     20    This patch has two parts:
     21    - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
     22    - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
     23      Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
     24   
     25    * b3/B3Validate.cpp:
     26    * wasm/WasmAirIRGenerator.cpp:
     27    (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
     28    (JSC::Wasm::AirIRGenerator::addLoop):
     29    * wasm/WasmB3IRGenerator.cpp:
     30    (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
     31    (JSC::Wasm::B3IRGenerator::addLoop):
     32    * wasm/WasmLLIntGenerator.cpp:
     33    (JSC::Wasm::LLIntGenerator::addLoop):
     34   
     35   
     36    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     37
     38    2021-07-30  Robin Morisset  <rmorisset@apple.com>
     39
     40            Improve OSR entry into Wasm loops with arguments
     41            https://bugs.webkit.org/show_bug.cgi?id=228595
     42
     43            Reviewed by Yusuke Suzuki.
     44
     45            This patch has two parts:
     46            - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
     47            - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
     48              Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
     49
     50            * b3/B3Validate.cpp:
     51            * wasm/WasmAirIRGenerator.cpp:
     52            (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
     53            (JSC::Wasm::AirIRGenerator::addLoop):
     54            * wasm/WasmB3IRGenerator.cpp:
     55            (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
     56            (JSC::Wasm::B3IRGenerator::addLoop):
     57            * wasm/WasmLLIntGenerator.cpp:
     58            (JSC::Wasm::LLIntGenerator::addLoop):
     59
    1602021-08-10  Russell Epstein  <repstein@apple.com>
    261
  • branches/safari-611.3.10.0-branch/Source/JavaScriptCore/b3/B3Validate.cpp

    r265074 r280849  
    573573            VALIDATE(block->numPredecessors() == predecessors.size(), ("At ", *block));
    574574        }
     575
     576        validatePhisAreDominatedByUpsilons();
    575577    }
    576578
     
    653655        VALIDATE(memory->offset() >= 0, ("At ", *value));
    654656    }
    655    
     657
     658    // A simple backwards analysis to check that we cannot reach a Phi without going through a corresponding Upsilon
     659    // We cannot use the dominator tree, since we are checking that each Phi is dominated by a the set of all of its upsilons, and not by a single node.
     660    void validatePhisAreDominatedByUpsilons()
     661    {
     662        bool changed = true;
     663        BitVector blocksToVisit;
     664        IndexMap<BasicBlock*, HashSet<Value*>> undominatedPhisAtTail(m_procedure.size());
     665        for (BasicBlock* block : m_procedure)
     666            blocksToVisit.set(block->index());
     667        while (changed) {
     668            changed = false;
     669            for (BasicBlock* block : m_procedure.blocksInPostOrder()) {
     670                if (!blocksToVisit.quickClear(block->index()))
     671                    continue;
     672                HashSet<Value*> undominatedPhis = undominatedPhisAtTail[block];
     673                for (unsigned index = block->size()-1; index--;) {
     674                    Value* value = block->at(index);
     675                    switch (value->opcode()) {
     676                    case Upsilon:
     677                        undominatedPhis.remove(value->as<UpsilonValue>()->phi());
     678                        break;
     679                    case Phi:
     680                        VALIDATE(!undominatedPhis.contains(value), ("At ", *value));
     681                        undominatedPhis.add(value);
     682                        break;
     683                    default:
     684                        break;
     685                    }
     686                }
     687                for (BasicBlock* predecessor : block->predecessors()) {
     688                    bool changedSet = false;
     689                    for (Value* phi : undominatedPhis)
     690                        changedSet |= undominatedPhisAtTail[predecessor].add(phi).isNewEntry;
     691                    if (changedSet) {
     692                        blocksToVisit.quickSet(predecessor->index());
     693                        changed = true;
     694                    }
     695                }
     696                if (!block->index())
     697                    VALIDATE(undominatedPhis.isEmpty(), ("Undominated phi at top of entry block: ", **undominatedPhis.begin()));
     698            }
     699        }
     700    }
     701
    656702    NO_RETURN_DUE_TO_CRASH void fail(
    657703        const char* filename, int lineNumber, const char* function, const char* condition,
  • branches/safari-611.3.10.0-branch/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp

    r270948 r280849  
    657657
    658658    void emitEntryTierUpCheck();
    659     void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack);
     659    void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack);
    660660
    661661    void emitWriteBarrierForJSWrapper();
     
    26412641}
    26422642
    2643 void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack)
     2643void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack)
    26442644{
    26452645    uint32_t outerLoopIndex = this->outerLoopIndex();
     
    26802680    }
    26812681    for (TypedExpression value : enclosingStack)
     2682        patchArgs.append(ConstrainedTmp(value.value(), B3::ValueRep::ColdAny));
     2683    for (TypedExpression value : newStack)
    26822684        patchArgs.append(ConstrainedTmp(value.value(), B3::ValueRep::ColdAny));
    26832685
     
    27322734
    27332735    m_currentBlock = body;
    2734     emitLoopTierUpCheck(loopIndex, enclosingStack);
     2736    emitLoopTierUpCheck(loopIndex, enclosingStack, newStack);
    27352737
    27362738    return { };
  • branches/safari-611.3.10.0-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r270948 r280849  
    296296
    297297    void emitEntryTierUpCheck();
    298     void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack);
     298    void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack);
    299299
    300300    void emitWriteBarrierForJSWrapper();
     
    18091809}
    18101810
    1811 void B3IRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack)
     1811void B3IRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack)
    18121812{
    18131813    uint32_t outerLoopIndex = this->outerLoopIndex();
     
    18351835    }
    18361836    for (TypedExpression value : enclosingStack)
     1837        stackmap.append(value);
     1838    for (TypedExpression value : newStack)
    18371839        stackmap.append(value);
    18381840
     
    18861888
    18871889    block = ControlData(m_proc, origin(), signature, BlockType::Loop, continuation, body);
    1888 
    1889     ExpressionList args;
    1890     {
    1891         unsigned offset = enclosingStack.size() - signature->argumentCount();
    1892         for (unsigned i = 0; i < signature->argumentCount(); ++i) {
    1893             TypedExpression value = enclosingStack.at(offset + i);
    1894             auto* upsilon = m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), value);
    1895             Value* phi = block.phis[i];
    1896             body->append(phi);
    1897             upsilon->setPhi(phi);
    1898             newStack.constructAndAppend(value.type(), phi);
    1899         }
    1900         enclosingStack.shrink(offset);
     1890    unsigned offset = enclosingStack.size() - signature->argumentCount();
     1891    for (unsigned i = 0; i < signature->argumentCount(); ++i) {
     1892        TypedExpression value = enclosingStack.at(offset + i);
     1893        auto* upsilon = m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), value);
     1894        Value* phi = block.phis[i];
     1895        body->append(phi);
     1896        upsilon->setPhi(phi);
     1897        newStack.constructAndAppend(value.type(), phi);
    19011898    }
    19021899
     
    19591956            connectControlEntry(data, expressionStack);
    19601957        }
     1958        for (unsigned i = 0; i < signature->argumentCount(); ++i) {
     1959            TypedExpression value = enclosingStack.at(offset + i);
     1960            Value* phi = block.phis[i];
     1961            m_currentBlock->appendNew<UpsilonValue>(m_proc, value->origin(), loadFromScratchBuffer(value->type()), phi);
     1962        }
     1963        enclosingStack.shrink(offset);
    19611964        connectControlEntry(block, enclosingStack);
    19621965
     
    19641967        m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body);
    19651968        body->addPredecessor(m_currentBlock);
    1966     }
     1969    } else
     1970        enclosingStack.shrink(offset);
    19671971
    19681972    m_currentBlock = body;
    1969     emitLoopTierUpCheck(loopIndex, enclosingStack);
     1973    emitLoopTierUpCheck(loopIndex, enclosingStack, newStack);
    19701974    return { };
    19711975}
  • branches/safari-611.3.10.0-branch/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp

    r276664 r280849  
    886886    for (TypedExpression expression : enclosingStack)
    887887        osrEntryData.append(expression);
     888    for (TypedExpression expression : newStack)
     889        osrEntryData.append(expression);
    888890
    889891    WasmLoopHint::emit(this);
Note: See TracChangeset for help on using the changeset viewer.