Ignore:
Timestamp:
Jul 24, 2013, 9:03:51 PM (12 years ago)
Author:
[email protected]
Message:

fourthTier: DFG should support switch_string
https://bugs.webkit.org/show_bug.cgi?id=117967

Source/JavaScriptCore:

Reviewed by Sam Weinig.

Add a reusable binary switch creator.

Implement switch on string using three modes:

  • Binary switch on StringImpl* in the case of identifiers.
  • Trie of binary switches on characters in the case of a not-too-big switch over not-too-big 8-bit strings.
  • Hash lookup if all else fails.

Anywhere from a 2x to 3x speed-up on microbenchmarks that stress
string switches. 25-35% speed-up on HashMap tests. 4% speed-up on
pdfjs.

(StringJumpTable):
(JSC::StringJumpTable::clear):

  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGBinarySwitch.cpp: Added.

(DFG):
(JSC::DFG::BinarySwitch::BinarySwitch):
(JSC::DFG::BinarySwitch::advance):
(JSC::DFG::BinarySwitch::build):

  • dfg/DFGBinarySwitch.h: Added.

(DFG):
(BinarySwitch):
(JSC::DFG::BinarySwitch::caseIndex):
(JSC::DFG::BinarySwitch::caseValue):
(JSC::DFG::BinarySwitch::fallThrough):
(JSC::DFG::BinarySwitch::Case::Case):
(Case):
(JSC::DFG::BinarySwitch::Case::operator<):
(JSC::DFG::BinarySwitch::BranchCode::BranchCode):
(BranchCode):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGLazyJSValue.cpp:

(JSC::DFG::LazyJSValue::getValue):
(JSC::DFG::equalToStringImpl):
(DFG):
(JSC::DFG::LazyJSValue::strictEqual):
(JSC::DFG::LazyJSValue::dump):

  • dfg/DFGLazyJSValue.h:

(JSC::DFG::LazyJSValue::knownStringImpl):
(LazyJSValue):
(JSC::DFG::LazyJSValue::stringImpl):
(JSC::DFG::LazyJSValue::switchLookupValue):

  • dfg/DFGNode.cpp:

(WTF::printInternal):

  • dfg/DFGNode.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::StringSwitchCase::operator<):
(DFG):
(JSC::DFG::SpeculativeJIT::emitBinarySwitchStringRecurse):
(JSC::DFG::SpeculativeJIT::emitSwitchStringOnString):
(JSC::DFG::SpeculativeJIT::emitSwitchString):
(JSC::DFG::SpeculativeJIT::emitSwitch):
(JSC::DFG::SpeculativeJIT::addBranch):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):
(JSC::DFG::SpeculativeJIT::branch8):
(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::StringSwitchCase::StringSwitchCase):
(StringSwitchCase):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileSwitch):

  • runtime/Options.h:

(JSC):

Source/WTF:

Reviewed by Sam Weinig.

Make it possible to compare a RefPtr<StringImpl> and a StringImpl* without
having to ref the StringImpl.

  • wtf/text/StringHash.h:

(WTF::StringHash::equal):

LayoutTests:

Reviewed by Sam Weinig.

  • fast/js/regress/script-tests/switch-string-basic-big-var.js: Added.

(foo):
(make):

  • fast/js/regress/script-tests/switch-string-basic-big.js: Added.

(foo):
(make):

  • fast/js/regress/script-tests/switch-string-basic-var.js: Added.

(foo):
(make):

  • fast/js/regress/script-tests/switch-string-basic.js: Added.

(foo):

  • fast/js/regress/script-tests/switch-string-big-length-tower-var.js: Added.

(foo):

  • fast/js/regress/script-tests/switch-string-length-tower-var.js: Added.

(foo):

  • fast/js/regress/script-tests/switch-string-length-tower.js: Added.

(foo):

  • fast/js/regress/script-tests/switch-string-short.js: Added.

(foo):

  • fast/js/regress/switch-string-basic-big-expected.txt: Added.
  • fast/js/regress/switch-string-basic-big-var-expected.txt: Added.
  • fast/js/regress/switch-string-basic-big-var.html: Added.
  • fast/js/regress/switch-string-basic-big.html: Added.
  • fast/js/regress/switch-string-basic-expected.txt: Added.
  • fast/js/regress/switch-string-basic-var-expected.txt: Added.
  • fast/js/regress/switch-string-basic-var.html: Added.
  • fast/js/regress/switch-string-basic.html: Added.
  • fast/js/regress/switch-string-big-length-tower-var-expected.txt: Added.
  • fast/js/regress/switch-string-big-length-tower-var.html: Added.
  • fast/js/regress/switch-string-length-tower-expected.txt: Added.
  • fast/js/regress/switch-string-length-tower-var-expected.txt: Added.
  • fast/js/regress/switch-string-length-tower-var.html: Added.
  • fast/js/regress/switch-string-length-tower.html: Added.
  • fast/js/regress/switch-string-short-expected.txt: Added.
  • fast/js/regress/switch-string-short.html: Added.

Conflicts:

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp

    r153234 r153248  
    4040    case SingleCharacterString:
    4141        return jsSingleCharacterString(&vm, u.character);
     42    case KnownStringImpl:
     43        return jsString(&vm, u.stringImpl);
    4244    }
    4345    RELEASE_ASSERT_NOT_REACHED();
     
    6062}
    6163
     64static TriState equalToStringImpl(JSValue value, StringImpl* stringImpl)
     65{
     66    if (!value.isString())
     67        return FalseTriState;
     68   
     69    JSString* jsString = asString(value);
     70    const StringImpl* string = jsString->tryGetValueImpl();
     71    if (!string)
     72        return MixedTriState;
     73   
     74    return triState(WTF::equal(stringImpl, string));
     75}
     76
    6277TriState LazyJSValue::strictEqual(const LazyJSValue& other) const
    6378{
     
    6984        case SingleCharacterString:
    7085            return equalToSingleCharacter(value(), other.character());
     86        case KnownStringImpl:
     87            return equalToStringImpl(value(), other.stringImpl());
    7188        }
    7289        break;
     
    7592        case SingleCharacterString:
    7693            return triState(character() == other.character());
     94        case KnownStringImpl:
     95            if (other.stringImpl()->length() != 1)
     96                return FalseTriState;
     97            return triState(other.stringImpl()->at(0) == character());
     98        default:
     99            return other.strictEqual(*this);
     100        }
     101        break;
     102    case KnownStringImpl:
     103        switch (other.m_kind) {
     104        case KnownStringImpl:
     105            return triState(WTF::equal(stringImpl(), other.stringImpl()));
    77106        default:
    78107            return other.strictEqual(*this);
     
    94123        out.print(" / ", StringImpl::utf8ForCharacters(&u.character, 1), ")");
    95124        return;
     125    case KnownStringImpl:
     126        out.print("Lazy:String(", stringImpl(), ")");
     127        return;
    96128    }
    97129    RELEASE_ASSERT_NOT_REACHED();
Note: See TracChangeset for help on using the changeset viewer.