Changeset 243642 in webkit
- Timestamp:
- Mar 28, 2019, 11:05:55 PM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 9 edited
-
ChangeLog (modified) (1 diff)
-
runtime/RegExp.cpp (modified) (2 diffs)
-
runtime/RegExpInlines.h (modified) (1 diff)
-
yarr/YarrInterpreter.cpp (modified) (2 diffs)
-
yarr/YarrJIT.cpp (modified) (23 diffs)
-
yarr/YarrPattern.cpp (modified) (10 diffs)
-
yarr/YarrPattern.h (modified) (6 diffs)
-
yarr/create_regex_tables (modified) (2 diffs)
-
yarr/generateYarrUnicodePropertyTables.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r243639 r243642 1 2019-03-28 Michael Saboff <msaboff@apple.com> 2 3 [YARR] Precompute BMP / non-BMP status when constructing character classes 4 https://bugs.webkit.org/show_bug.cgi?id=196296 5 6 Reviewed by Keith Miller. 7 8 Changed CharacterClass::m_hasNonBMPCharacters into a character width bit field which 9 indicateis if the class includes characters from either BMP, non-BMP or both ranges. 10 This allows the recognizing code to eliminate checks for the width of a matched 11 characters when the class has only one width. The character width is needed to 12 determine if we advance 1 or 2 character. Also, the pre-computed width of character 13 classes that contains either all BMP or all non-BMP characters allows the parser to 14 use fixed widths for terms using those character classes. Changed both the code gen 15 scripts and Yarr compiler to compute this bit field during the construction of 16 character classes. 17 18 For JIT'ed code of character classes that contain either all BMP or all non-BMP 19 characters, we can eliminate the generic check we were doing do compute how much 20 to advance after sucessfully matching a character in the class. 21 22 Generic isBMP check BMP only non-BMP only 23 -------------- -------------- -------------- 24 inc %r9d inc %r9d add $0x2, %r9d 25 cmp $0x10000, %eax 26 jl isBMP 27 cmp %edx, %esi 28 jz atEndOfString 29 inc %r9d 30 inc %esi 31 isBMP: 32 33 For character classes that contained non-BMP characters, we were always generating 34 the code in the left column. The middle column is the code we generate for character 35 classes that contain only BMP characters. The right column is the code we now 36 generate if the character class has only non-BMP characters. In the fix width cases, 37 we can eliminate both the isBMP check as well as the atEndOfString check. The 38 atEndOfstring check is eliminated since we know how many characters this character 39 class requires and that check can be factored out to the beginning of the current 40 alternative. For character classes that contain both BMP and non-BMP characters, 41 we still generate the generic left column. 42 43 This change is a ~8% perf progression on UniPoker and a ~2% improvement on RexBench 44 as a whole. 45 46 * runtime/RegExp.cpp: 47 (JSC::RegExp::matchCompareWithInterpreter): 48 * runtime/RegExpInlines.h: 49 (JSC::RegExp::matchInline): 50 * yarr/YarrInterpreter.cpp: 51 (JSC::Yarr::Interpreter::checkCharacterClassDontAdvanceInputForNonBMP): 52 (JSC::Yarr::Interpreter::matchCharacterClass): 53 * yarr/YarrJIT.cpp: 54 (JSC::Yarr::YarrGenerator::optimizeAlternative): 55 (JSC::Yarr::YarrGenerator::matchCharacterClass): 56 (JSC::Yarr::YarrGenerator::advanceIndexAfterCharacterClassTermMatch): 57 (JSC::Yarr::YarrGenerator::tryReadUnicodeCharImpl): 58 (JSC::Yarr::YarrGenerator::generateCharacterClassOnce): 59 (JSC::Yarr::YarrGenerator::generateCharacterClassFixed): 60 (JSC::Yarr::YarrGenerator::generateCharacterClassGreedy): 61 (JSC::Yarr::YarrGenerator::backtrackCharacterClassGreedy): 62 (JSC::Yarr::YarrGenerator::generateCharacterClassNonGreedy): 63 (JSC::Yarr::YarrGenerator::backtrackCharacterClassNonGreedy): 64 (JSC::Yarr::YarrGenerator::generateEnter): 65 (JSC::Yarr::YarrGenerator::YarrGenerator): 66 (JSC::Yarr::YarrGenerator::compile): 67 * yarr/YarrPattern.cpp: 68 (JSC::Yarr::CharacterClassConstructor::CharacterClassConstructor): 69 (JSC::Yarr::CharacterClassConstructor::reset): 70 (JSC::Yarr::CharacterClassConstructor::charClass): 71 (JSC::Yarr::CharacterClassConstructor::addSorted): 72 (JSC::Yarr::CharacterClassConstructor::addSortedRange): 73 (JSC::Yarr::CharacterClassConstructor::hasNonBMPCharacters): 74 (JSC::Yarr::CharacterClassConstructor::characterWidths): 75 (JSC::Yarr::PatternTerm::dump): 76 (JSC::Yarr::anycharCreate): 77 * yarr/YarrPattern.h: 78 (JSC::Yarr::operator|): 79 (JSC::Yarr::operator&): 80 (JSC::Yarr::operator|=): 81 (JSC::Yarr::CharacterClass::CharacterClass): 82 (JSC::Yarr::CharacterClass::hasNonBMPCharacters): 83 (JSC::Yarr::CharacterClass::hasOneCharacterSize): 84 (JSC::Yarr::CharacterClass::hasOnlyNonBMPCharacters): 85 (JSC::Yarr::PatternTerm::invert const): 86 (JSC::Yarr::PatternTerm::invert): Deleted. 87 * yarr/create_regex_tables: 88 * yarr/generateYarrUnicodePropertyTables.py: 89 1 90 2019-03-28 Saam Barati <sbarati@apple.com> 2 91 -
trunk/Source/JavaScriptCore/runtime/RegExp.cpp
r243408 r243642 386 386 interpreterOffsetVector[j] = -1; 387 387 388 interpreterResult = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, interpreterOffsetVector);388 interpreterResult = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, reinterpret_cast<unsigned*>(interpreterOffsetVector)); 389 389 390 390 if (jitResult != interpreterResult) … … 403 403 404 404 if (jitResult != interpreterResult) { 405 dataLogF(" JIT result = %d, blahinterpreted result = %d\n", jitResult, interpreterResult);405 dataLogF(" JIT result = %d, interpreted result = %d\n", jitResult, interpreterResult); 406 406 differences--; 407 407 } else { -
trunk/Source/JavaScriptCore/runtime/RegExpInlines.h
r243408 r243642 182 182 183 183 #if ENABLE(YARR_JIT_DEBUG) 184 matchCompareWithInterpreter(s, startOffset, offsetVector, result); 184 if (m_state == JITCode) { 185 byteCodeCompileIfNecessary(&vm); 186 matchCompareWithInterpreter(s, startOffset, offsetVector, result); 187 } 185 188 #endif 186 189 } else -
trunk/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
r243237 r243642 429 429 return invert ? !match : match; 430 430 } 431 432 bool checkCharacterClassDontAdvanceInputForNonBMP(CharacterClass* characterClass, unsigned negativeInputOffset) 433 { 434 int readCharacter = characterClass->hasOnlyNonBMPCharacters() ? input.readSurrogatePairChecked(negativeInputOffset) : input.readChecked(negativeInputOffset); 435 return testCharacterClass(characterClass, readCharacter); 436 } 431 437 432 438 bool tryConsumeBackReference(int matchBegin, int matchEnd, unsigned negativeInputOffset) … … 559 565 case QuantifierFixedCount: { 560 566 if (unicode) { 567 CharacterClass* charClass = term.atom.characterClass; 561 568 backTrack->begin = input.getPos(); 562 569 unsigned matchAmount = 0; 563 570 for (matchAmount = 0; matchAmount < term.atom.quantityMaxCount; ++matchAmount) { 564 if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition - matchAmount)) { 565 input.setPos(backTrack->begin); 566 return false; 571 if (term.invert()) { 572 if (!checkCharacterClass(charClass, term.invert(), term.inputPosition - matchAmount)) { 573 input.setPos(backTrack->begin); 574 return false; 575 } 576 } else { 577 unsigned matchOffset = matchAmount * (charClass->hasOnlyNonBMPCharacters() ? 2 : 1); 578 if (!checkCharacterClassDontAdvanceInputForNonBMP(charClass, term.inputPosition - matchOffset)) { 579 input.setPos(backTrack->begin); 580 return false; 581 } 567 582 } 568 583 } -
trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp
r243237 r243642 73 73 static const RegisterID initialStart = ARM64Registers::x11; 74 74 static const RegisterID supplementaryPlanesBase = ARM64Registers::x12; 75 static const RegisterID surrogateTagMask= ARM64Registers::x13;76 static const RegisterID leadingSurrogateTag = ARM64Registers::x14;77 static const RegisterID trailingSurrogateTag= ARM64Registers::x15;75 static const RegisterID leadingSurrogateTag = ARM64Registers::x13; 76 static const RegisterID trailingSurrogateTag = ARM64Registers::x14; 77 static const RegisterID endOfStringAddress = ARM64Registers::x15; 78 78 79 79 static const RegisterID returnRegister = ARM64Registers::x0; 80 80 static const RegisterID returnRegister2 = ARM64Registers::x1; 81 81 82 const TrustedImm32 surrogateTagMask = TrustedImm32(0xfffffc00); 82 83 #define HAVE_INITIAL_START_REG 83 84 #define JIT_UNICODE_EXPRESSIONS … … 144 145 static const RegisterID regUnicodeInputAndTrail = X86Registers::r13; 145 146 static const RegisterID leadingSurrogateTag = X86Registers::r14; 146 static const RegisterID trailingSurrogateTag= X86Registers::r15;147 static const RegisterID endOfStringAddress = X86Registers::r15; 147 148 148 149 static const RegisterID returnRegister = X86Registers::eax; … … 150 151 151 152 const TrustedImm32 supplementaryPlanesBase = TrustedImm32(0x10000); 153 const TrustedImm32 trailingSurrogateTag = TrustedImm32(0xdc00); 152 154 const TrustedImm32 surrogateTagMask = TrustedImm32(0xfffffc00); 153 155 #define HAVE_INITIAL_START_REG … … 320 322 if ((term.type == PatternTerm::TypeCharacterClass) 321 323 && (term.quantityType == QuantifierFixedCount) 322 && (!m_decodeSurrogatePairs || ( !term.characterClass->m_hasNonBMPCharacters&& !term.m_invert))324 && (!m_decodeSurrogatePairs || (term.characterClass->hasOneCharacterSize() && !term.m_invert)) 323 325 && (nextTerm.type == PatternTerm::TypePatternCharacter) 324 326 && (nextTerm.quantityType == QuantifierFixedCount)) { … … 384 386 return; 385 387 } 388 386 389 JumpList unicodeFail; 387 390 if (charClass->m_matchesUnicode.size() || charClass->m_rangesUnicode.size()) { … … 448 451 unicodeFail.link(this); 449 452 } 453 454 #ifdef JIT_UNICODE_EXPRESSIONS 455 void advanceIndexAfterCharacterClassTermMatch(const PatternTerm* term, JumpList& failures, const RegisterID character) 456 { 457 ASSERT(term->type == PatternTerm::TypeCharacterClass); 458 459 if (term->characterClass->hasOneCharacterSize() && !term->invert()) 460 add32(TrustedImm32(term->characterClass->hasNonBMPCharacters() ? 2 : 1), index); 461 else { 462 add32(TrustedImm32(1), index); 463 failures.append(atEndOfInput()); 464 Jump isBMPChar = branch32(LessThan, character, supplementaryPlanesBase); 465 add32(TrustedImm32(1), index); 466 isBMPChar.link(this); 467 } 468 } 469 #endif 450 470 451 471 // Jumps if input not available; will have (incorrectly) incremented already! … … 521 541 522 542 JumpList notUnicode; 543 523 544 load16Unaligned(regUnicodeInputAndTrail, resultReg); 524 545 and32(surrogateTagMask, resultReg, regT2); 525 546 notUnicode.append(branch32(NotEqual, regT2, leadingSurrogateTag)); 526 547 addPtr(TrustedImm32(2), regUnicodeInputAndTrail); 527 getEffectiveAddress(BaseIndex(input, length, TimesTwo), regT2); 528 notUnicode.append(branch32(AboveOrEqual, regUnicodeInputAndTrail, regT2)); 548 notUnicode.append(branchPtr(AboveOrEqual, regUnicodeInputAndTrail, endOfStringAddress)); 529 549 load16Unaligned(Address(regUnicodeInputAndTrail), regUnicodeInputAndTrail); 530 550 and32(surrogateTagMask, regUnicodeInputAndTrail, regT2); … … 1735 1755 } 1736 1756 #ifdef JIT_UNICODE_EXPRESSIONS 1737 if (m_decodeSurrogatePairs ) {1757 if (m_decodeSurrogatePairs && (!term->characterClass->hasOneCharacterSize() || term->invert())) { 1738 1758 Jump isBMPChar = branch32(LessThan, character, supplementaryPlanesBase); 1739 1759 add32(TrustedImm32(1), index); … … 1769 1789 1770 1790 move(index, countRegister); 1771 sub32(Imm32(term->quantityMaxCount.unsafeGet()), countRegister); 1791 1792 Checked<unsigned> scaledMaxCount = term->quantityMaxCount; 1793 1794 #ifdef JIT_UNICODE_EXPRESSIONS 1795 if (m_decodeSurrogatePairs && term->characterClass->hasOnlyNonBMPCharacters() && !term->invert()) 1796 scaledMaxCount *= 2; 1797 #endif 1798 sub32(Imm32(scaledMaxCount.unsafeGet()), countRegister); 1772 1799 1773 1800 Label loop(this); 1774 1801 JumpList matchDest; 1775 readCharacter(m_checkedOffset - term->inputPosition - term->quantityMaxCount, character, countRegister);1802 readCharacter(m_checkedOffset - term->inputPosition - scaledMaxCount, character, countRegister); 1776 1803 // If we are matching the "any character" builtin class we only need to read the 1777 1804 // character and don't need to match as it will always succeed. … … 1787 1814 } 1788 1815 1789 add32(TrustedImm32(1), countRegister);1790 1816 #ifdef JIT_UNICODE_EXPRESSIONS 1791 1817 if (m_decodeSurrogatePairs) { 1792 Jump isBMPChar = branch32(LessThan, character, supplementaryPlanesBase); 1793 op.m_jumps.append(atEndOfInput()); 1818 if (term->characterClass->hasOneCharacterSize() && !term->invert()) 1819 add32(TrustedImm32(term->characterClass->hasNonBMPCharacters() ? 2 : 1), countRegister); 1820 else { 1821 add32(TrustedImm32(1), countRegister); 1822 Jump isBMPChar = branch32(LessThan, character, supplementaryPlanesBase); 1823 op.m_jumps.append(atEndOfInput()); 1824 add32(TrustedImm32(1), countRegister); 1825 add32(TrustedImm32(1), index); 1826 isBMPChar.link(this); 1827 } 1828 } else 1829 #endif 1794 1830 add32(TrustedImm32(1), countRegister); 1795 add32(TrustedImm32(1), index);1796 isBMPChar.link(this);1797 }1798 #endif1799 1831 branch32(NotEqual, countRegister, index).linkTo(loop, this); 1800 1832 } … … 1812 1844 const RegisterID countRegister = regT1; 1813 1845 1814 if (m_decodeSurrogatePairs )1846 if (m_decodeSurrogatePairs && (!term->characterClass->hasOneCharacterSize() || term->invert())) 1815 1847 storeToFrame(index, term->frameLocation + BackTrackInfoCharacterClass::beginIndex()); 1816 1848 move(TrustedImm32(0), countRegister); … … 1826 1858 JumpList matchDest; 1827 1859 readCharacter(m_checkedOffset - term->inputPosition, character); 1828 // If we are matching the "any character" builtin class we only need to read the1829 // character and don't need to match as it will always succeed.1860 // If we are matching the "any character" builtin class for non-unicode patterns, 1861 // we only need to read the character and don't need to match as it will always succeed. 1830 1862 if (!term->characterClass->m_anyCharacter) { 1831 1863 matchCharacterClass(character, matchDest, term->characterClass); … … 1835 1867 } 1836 1868 1837 add32(TrustedImm32(1), index);1838 1869 #ifdef JIT_UNICODE_EXPRESSIONS 1839 if (m_decodeSurrogatePairs) { 1840 failures.append(atEndOfInput()); 1841 Jump isBMPChar = branch32(LessThan, character, supplementaryPlanesBase); 1870 if (m_decodeSurrogatePairs) 1871 advanceIndexAfterCharacterClassTermMatch(term, failures, character); 1872 else 1873 #endif 1842 1874 add32(TrustedImm32(1), index); 1843 isBMPChar.link(this);1844 }1845 #endif1846 1875 add32(TrustedImm32(1), countRegister); 1847 1876 … … 1869 1898 m_backtrackingState.append(branchTest32(Zero, countRegister)); 1870 1899 sub32(TrustedImm32(1), countRegister); 1900 storeToFrame(countRegister, term->frameLocation + BackTrackInfoCharacterClass::matchAmountIndex()); 1901 1871 1902 if (!m_decodeSurrogatePairs) 1872 1903 sub32(TrustedImm32(1), index); 1904 else if (term->characterClass->hasOneCharacterSize() && !term->invert()) 1905 sub32(TrustedImm32(term->characterClass->hasNonBMPCharacters() ? 2 : 1), index); 1873 1906 else { 1907 // Rematch one less 1874 1908 const RegisterID character = regT0; 1875 1909 1876 1910 loadFromFrame(term->frameLocation + BackTrackInfoCharacterClass::beginIndex(), index); 1877 // Rematch one less1878 storeToFrame(countRegister, term->frameLocation + BackTrackInfoCharacterClass::matchAmountIndex());1879 1911 1880 1912 Label rematchLoop(this); … … 1906 1938 move(TrustedImm32(0), countRegister); 1907 1939 op.m_reentry = label(); 1908 if (m_decodeSurrogatePairs) 1909 storeToFrame(index, term->frameLocation + BackTrackInfoCharacterClass::beginIndex()); 1910 storeToFrame(countRegister, term->frameLocation + BackTrackInfoCharacterClass::matchAmountIndex()); 1940 if (m_decodeSurrogatePairs) { 1941 if (!term->characterClass->hasOneCharacterSize() || term->invert()) 1942 storeToFrame(index, term->frameLocation + BackTrackInfoCharacterClass::beginIndex()); 1943 storeToFrame(countRegister, term->frameLocation + BackTrackInfoCharacterClass::matchAmountIndex()); 1944 } 1911 1945 } 1912 1946 … … 1923 1957 m_backtrackingState.link(this); 1924 1958 1925 if (m_decodeSurrogatePairs) 1926 loadFromFrame(term->frameLocation + BackTrackInfoCharacterClass::beginIndex(), index); 1927 loadFromFrame(term->frameLocation + BackTrackInfoCharacterClass::matchAmountIndex(), countRegister); 1959 if (m_decodeSurrogatePairs) { 1960 if (!term->characterClass->hasOneCharacterSize() || term->invert()) 1961 loadFromFrame(term->frameLocation + BackTrackInfoCharacterClass::beginIndex(), index); 1962 loadFromFrame(term->frameLocation + BackTrackInfoCharacterClass::matchAmountIndex(), countRegister); 1963 } 1928 1964 1929 1965 nonGreedyFailures.append(atEndOfInput()); … … 1932 1968 JumpList matchDest; 1933 1969 readCharacter(m_checkedOffset - term->inputPosition, character); 1934 // If we are matching the "any character" builtin class we only need to read the1935 // character and don't need to match as it will always succeed.1970 // If we are matching the "any character" builtin class for non-unicode patterns, 1971 // we only need to read the character and don't need to match as it will always succeed. 1936 1972 if (term->invert() || !term->characterClass->m_anyCharacter) { 1937 1973 matchCharacterClass(character, matchDest, term->characterClass); … … 1945 1981 } 1946 1982 1947 add32(TrustedImm32(1), index);1948 1983 #ifdef JIT_UNICODE_EXPRESSIONS 1949 if (m_decodeSurrogatePairs) { 1950 nonGreedyFailures.append(atEndOfInput()); 1951 Jump isBMPChar = branch32(LessThan, character, supplementaryPlanesBase); 1984 if (m_decodeSurrogatePairs) 1985 advanceIndexAfterCharacterClassTermMatch(term, nonGreedyFailures, character); 1986 else 1987 #endif 1952 1988 add32(TrustedImm32(1), index); 1953 isBMPChar.link(this);1954 }1955 #endif1956 1989 add32(TrustedImm32(1), countRegister); 1957 1990 … … 3701 3734 3702 3735 move(TrustedImm32(0xd800), leadingSurrogateTag); 3703 move(TrustedImm32(0xdc00), trailingSurrogateTag);3704 3736 } 3705 3737 // The ABI doesn't guarantee the upper bits are zero on unsigned arguments, so clear them ourselves. … … 3735 3767 pushPair(framePointerRegister, linkRegister); 3736 3768 move(TrustedImm32(0x10000), supplementaryPlanesBase); 3737 move(TrustedImm32(0xfffffc00), surrogateTagMask);3738 3769 move(TrustedImm32(0xd800), leadingSurrogateTag); 3739 3770 move(TrustedImm32(0xdc00), trailingSurrogateTag); … … 3816 3847 , m_decodeSurrogatePairs(m_charSize == Char16 && m_pattern.unicode()) 3817 3848 , m_unicodeIgnoreCase(m_pattern.unicode() && m_pattern.ignoreCase()) 3849 , m_fixedSizedAlternative(false) 3818 3850 , m_canonicalMode(m_pattern.unicode() ? CanonicalMode::Unicode : CanonicalMode::UCS2) 3819 3851 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) … … 3869 3901 generateFailReturn(); 3870 3902 hasInput.link(this); 3903 3904 #ifdef JIT_UNICODE_EXPRESSIONS 3905 if (m_decodeSurrogatePairs) 3906 getEffectiveAddress(BaseIndex(input, length, TimesTwo), endOfStringAddress); 3907 #endif 3871 3908 3872 3909 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) … … 4164 4201 bool m_decodeSurrogatePairs; 4165 4202 bool m_unicodeIgnoreCase; 4203 bool m_fixedSizedAlternative; 4166 4204 CanonicalMode m_canonicalMode; 4167 4205 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) -
trunk/Source/JavaScriptCore/yarr/YarrPattern.cpp
r242699 r243642 46 46 CharacterClassConstructor(bool isCaseInsensitive, CanonicalMode canonicalMode) 47 47 : m_isCaseInsensitive(isCaseInsensitive) 48 , m_hasNonBMPCharacters(false)49 48 , m_anyCharacter(false) 49 , m_characterWidths(CharacterClassWidths::Unknown) 50 50 , m_canonicalMode(canonicalMode) 51 51 { … … 58 58 m_matchesUnicode.clear(); 59 59 m_rangesUnicode.clear(); 60 m_hasNonBMPCharacters = false;61 60 m_anyCharacter = false; 61 m_characterWidths = CharacterClassWidths::Unknown; 62 62 } 63 63 … … 247 247 characterClass->m_matchesUnicode.swap(m_matchesUnicode); 248 248 characterClass->m_rangesUnicode.swap(m_rangesUnicode); 249 characterClass->m_hasNonBMPCharacters = hasNonBMPCharacters();250 249 characterClass->m_anyCharacter = anyCharacter(); 251 252 m_hasNonBMPCharacters = false; 250 characterClass->m_characterWidths = characterWidths(); 251 253 252 m_anyCharacter = false; 253 m_characterWidths = CharacterClassWidths::Unknown; 254 254 255 255 return characterClass; … … 267 267 unsigned range = matches.size(); 268 268 269 if (!U_IS_BMP(ch)) 270 m_hasNonBMPCharacters = true; 269 m_characterWidths |= (U_IS_BMP(ch) ? CharacterClassWidths::HasBMPChars : CharacterClassWidths::HasNonBMPChars); 271 270 272 271 // binary chop, find position to insert char. … … 317 316 size_t end = ranges.size(); 318 317 318 if (U_IS_BMP(lo)) 319 m_characterWidths |= CharacterClassWidths::HasBMPChars; 319 320 if (!U_IS_BMP(hi)) 320 m_ hasNonBMPCharacters = true;321 m_characterWidths |= CharacterClassWidths::HasNonBMPChars; 321 322 322 323 // Simple linear scan - I doubt there are that many ranges anyway... … … 409 410 bool hasNonBMPCharacters() 410 411 { 411 return m_hasNonBMPCharacters; 412 return m_characterWidths & CharacterClassWidths::HasNonBMPChars; 413 } 414 415 CharacterClassWidths characterWidths() 416 { 417 return m_characterWidths; 412 418 } 413 419 … … 418 424 419 425 bool m_isCaseInsensitive : 1; 420 bool m_hasNonBMPCharacters : 1;421 426 bool m_anyCharacter : 1; 427 CharacterClassWidths m_characterWidths; 428 422 429 CanonicalMode m_canonicalMode; 423 430 … … 837 844 term.frameLocation = currentCallFrameSize; 838 845 currentCallFrameSize += YarrStackSpaceForBackTrackInfoCharacterClass; 839 currentInputPosition += term.quantityMaxCount; 840 alternative->m_hasFixedSize = false; 846 if (term.characterClass->hasOneCharacterSize() && !term.invert()) { 847 Checked<unsigned, RecordOverflow> tempCount = term.quantityMaxCount; 848 tempCount *= term.characterClass->hasNonBMPCharacters() ? 2 : 1; 849 if (tempCount.hasOverflowed()) 850 return ErrorCode::OffsetTooLarge; 851 currentInputPosition += tempCount; 852 } else { 853 currentInputPosition += term.quantityMaxCount; 854 alternative->m_hasFixedSize = false; 855 } 841 856 } else 842 857 currentInputPosition += term.quantityMaxCount; … … 1319 1334 case TypeCharacterClass: 1320 1335 out.print("character class "); 1336 out.printf("inputPosition %u ", inputPosition); 1321 1337 dumpCharacterClass(out, thisPattern, characterClass); 1322 1338 dumpQuantifier(out); … … 1462 1478 characterClass->m_ranges.append(CharacterRange(0x00, 0x7f)); 1463 1479 characterClass->m_rangesUnicode.append(CharacterRange(0x0080, 0x10ffff)); 1464 characterClass->m_ hasNonBMPCharacters = true;1480 characterClass->m_characterWidths = CharacterClassWidths::HasBothBMPAndNonBMP; 1465 1481 characterClass->m_anyCharacter = true; 1466 1482 return characterClass; -
trunk/Source/JavaScriptCore/yarr/YarrPattern.h
r242699 r243642 53 53 }; 54 54 55 enum struct CharacterClassWidths : unsigned char { 56 Unknown = 0x0, 57 HasBMPChars = 0x1, 58 HasNonBMPChars = 0x2, 59 HasBothBMPAndNonBMP = HasBMPChars | HasNonBMPChars 60 }; 61 62 inline CharacterClassWidths operator|(CharacterClassWidths lhs, CharacterClassWidths rhs) 63 { 64 return static_cast<CharacterClassWidths>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); 65 } 66 67 inline bool operator&(CharacterClassWidths lhs, CharacterClassWidths rhs) 68 { 69 return static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs); 70 } 71 72 inline CharacterClassWidths& operator|=(CharacterClassWidths& lhs, CharacterClassWidths rhs) 73 { 74 lhs = lhs | rhs; 75 return lhs; 76 } 77 55 78 struct CharacterClass { 56 79 WTF_MAKE_FAST_ALLOCATED; … … 61 84 CharacterClass() 62 85 : m_table(0) 63 , m_ hasNonBMPCharacters(false)86 , m_characterWidths(CharacterClassWidths::Unknown) 64 87 , m_anyCharacter(false) 65 88 { … … 67 90 CharacterClass(const char* table, bool inverted) 68 91 : m_table(table) 92 , m_characterWidths(CharacterClassWidths::Unknown) 69 93 , m_tableInverted(inverted) 70 , m_hasNonBMPCharacters(false)71 94 , m_anyCharacter(false) 72 95 { 73 96 } 74 CharacterClass(std::initializer_list<UChar32> matches, std::initializer_list<CharacterRange> ranges, std::initializer_list<UChar32> matchesUnicode, std::initializer_list<CharacterRange> rangesUnicode )97 CharacterClass(std::initializer_list<UChar32> matches, std::initializer_list<CharacterRange> ranges, std::initializer_list<UChar32> matchesUnicode, std::initializer_list<CharacterRange> rangesUnicode, CharacterClassWidths widths) 75 98 : m_matches(matches) 76 99 , m_ranges(ranges) … … 78 101 , m_rangesUnicode(rangesUnicode) 79 102 , m_table(0) 103 , m_characterWidths(widths) 80 104 , m_tableInverted(false) 81 , m_hasNonBMPCharacters(false)82 105 , m_anyCharacter(false) 83 106 { 84 107 } 85 108 109 bool hasNonBMPCharacters() { return m_characterWidths & CharacterClassWidths::HasNonBMPChars; } 110 111 bool hasOneCharacterSize() { return m_characterWidths == CharacterClassWidths::HasBMPChars || m_characterWidths == CharacterClassWidths::HasNonBMPChars; } 112 bool hasOnlyNonBMPCharacters() { return m_characterWidths == CharacterClassWidths::HasNonBMPChars; } 113 86 114 Vector<UChar32> m_matches; 87 115 Vector<CharacterRange> m_ranges; … … 90 118 91 119 const char* m_table; 120 CharacterClassWidths m_characterWidths; 92 121 bool m_tableInverted : 1; 93 bool m_hasNonBMPCharacters : 1;94 122 bool m_anyCharacter : 1; 95 123 }; … … 221 249 } 222 250 223 bool invert() 251 bool invert() const 224 252 { 225 253 return m_invert; -
trunk/Source/JavaScriptCore/yarr/create_regex_tables
r238004 r243642 101 101 else: 102 102 function += (" auto characterClass = std::make_unique<CharacterClass>();\n") 103 hasBMPCharacters = False 103 104 hasNonBMPCharacters = False 104 105 for (min, max) in ranges: 106 if min < 0x10000: 107 hasBMPCharacters = True 108 if max >= 0x10000: 109 hasNonBMPCharacters = True 105 110 if (min == max): 106 111 if (min > 127): … … 113 118 else: 114 119 function += (" characterClass->m_ranges.append(CharacterRange(0x%02x, 0x%02x));\n" % (min, max)) 115 if max >= 0x10000: 116 hasNonBMPCharacters = True 117 function += (" characterClass->m_hasNonBMPCharacters = %s;\n" % ("true" if hasNonBMPCharacters else "false")) 120 function += (" characterClass->m_characterWidths = CharacterClassWidths::%s;\n" % (("Unknown", "HasBMPChars", "HasNonBMPChars", "HasBothBMPAndNonBMP")[int(hasNonBMPCharacters) * 2 + int(hasBMPCharacters)])) 118 121 function += (" return characterClass;\n") 119 122 function += ("}\n\n") -
trunk/Source/JavaScriptCore/yarr/generateYarrUnicodePropertyTables.py
r236870 r243642 36 36 37 37 header = """/* 38 * Copyright (C) 2017-201 8Apple Inc. All rights reserved.38 * Copyright (C) 2017-2019 Apple Inc. All rights reserved. 39 39 * 40 40 * Redistribution and use in source and binary forms, with or without … … 226 226 self.aliases = [] 227 227 self.index = len(PropertyData.allPropertyData) 228 self.hasBMPCharacters = False 228 229 self.hasNonBMPCharacters = False 229 230 self.matches = [] … … 250 251 251 252 def addMatch(self, codePoint): 252 if codePoint > MaxBMP: 253 if codePoint <= MaxBMP: 254 self.hasBMPCharacters = True 255 else: 253 256 self.hasNonBMPCharacters = True 254 257 if codePoint <= lastASCIICodePoint: … … 282 285 283 286 def addRange(self, lowCodePoint, highCodePoint): 287 if lowCodePoint <= MaxBMP: 288 self.hasBMPCharacters = True 284 289 if highCodePoint > MaxBMP: 285 290 self.hasNonBMPCharacters = True … … 537 542 file.write(" std::initializer_list<CharacterRange>(") 538 543 self.dumpMatchData(file, 4, self.unicodeRanges, lambda file, range: (file.write("{{{0:0=#6x}, {1:0=#6x}}}".format(range[0], range[1])))) 539 file.write(") );\n")540 541 file.write(" characterClass->m_hasNonBMPCharacters = {};\n".format(("false", "true")[self.hasNonBMPCharacters]))544 file.write("),\n") 545 546 file.write(" CharacterClassWidths::{});\n".format(("Unknown", "HasBMPChars", "HasNonBMPChars", "HasBothBMPAndNonBMP")[int(self.hasNonBMPCharacters) * 2 + int(self.hasBMPCharacters)])) 542 547 file.write(" return characterClass;\n}\n\n") 543 548
Note:
See TracChangeset
for help on using the changeset viewer.