Changeset 112454 in webkit for trunk/Source/JavaScriptCore/yarr
- Timestamp:
- Mar 28, 2012, 3:18:20 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore/yarr
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp
r112192 r112454 38 38 namespace JSC { namespace Yarr { 39 39 40 template<YarrJITCompileMode compileMode> 40 41 class YarrGenerator : private MacroAssembler { 41 42 friend void jitCompile(JSGlobalData*, YarrCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline); … … 51 52 52 53 static const RegisterID returnRegister = ARMRegisters::r0; 54 static const RegisterID returnRegister2 = ARMRegisters::r1; 53 55 #elif CPU(MIPS) 54 56 static const RegisterID input = MIPSRegisters::a0; … … 61 63 62 64 static const RegisterID returnRegister = MIPSRegisters::v0; 65 static const RegisterID returnRegister2 = MIPSRegisters::v1; 63 66 #elif CPU(SH4) 64 67 static const RegisterID input = SH4Registers::r4; … … 71 74 72 75 static const RegisterID returnRegister = SH4Registers::r0; 76 static const RegisterID returnRegister2 = SH4Registers::r1; 73 77 #elif CPU(X86) 74 78 static const RegisterID input = X86Registers::eax; … … 81 85 82 86 static const RegisterID returnRegister = X86Registers::eax; 87 static const RegisterID returnRegister2 = X86Registers::edx; 83 88 #elif CPU(X86_64) 84 89 static const RegisterID input = X86Registers::edi; … … 91 96 92 97 static const RegisterID returnRegister = X86Registers::eax; 98 static const RegisterID returnRegister2 = X86Registers::edx; 93 99 #endif 94 100 … … 304 310 { 305 311 jump(Address(stackPointerRegister, frameLocation * sizeof(void*))); 312 } 313 314 void initCallFrame() 315 { 316 unsigned callFrameSize = m_pattern.m_body->m_callFrameSize; 317 if (callFrameSize) 318 subPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister); 319 } 320 void removeCallFrame() 321 { 322 unsigned callFrameSize = m_pattern.m_body->m_callFrameSize; 323 if (callFrameSize) 324 addPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister); 325 } 326 327 // Used to record subpatters, should only be called if compileMode is IncludeSubpatterns. 328 void setSubpatternStart(RegisterID reg, unsigned subpattern) 329 { 330 ASSERT(subpattern); 331 ASSERT(compileMode == IncludeSubpatterns); 332 store32(reg, Address(output, (subpattern << 1) * sizeof(int))); 333 } 334 void setSubpatternEnd(RegisterID reg, unsigned subpattern) 335 { 336 ASSERT(subpattern); 337 ASSERT(compileMode == IncludeSubpatterns); 338 store32(reg, Address(output, ((subpattern << 1) + 1) * sizeof(int))); 339 } 340 void clearSubpatternStart(unsigned subpattern) 341 { 342 ASSERT(subpattern); 343 ASSERT(compileMode == IncludeSubpatterns); 344 store32(TrustedImm32(-1), Address(output, (subpattern << 1) * sizeof(int))); 345 } 346 347 // We use one of three different strategies to track the start of the current match, 348 // while matching. 349 // 1) If the pattern has a fixed size, do nothing! - we calculate the value lazily 350 // at the end of matching. This is irrespective of compileMode, and in this case 351 // these methods should never be called. 352 // 2) If we're compiling IncludeSubpatterns, 'output' contains a pointer to an output 353 // vector, store the match start in the output vector. 354 // 3) If we're compiling MatchOnly, 'output' is unused, store the match start directly 355 // in this register. 356 void setMatchStart(RegisterID reg) 357 { 358 ASSERT(!m_pattern.m_body->m_hasFixedSize); 359 if (compileMode == IncludeSubpatterns) 360 store32(reg, output); 361 else 362 move(reg, output); 363 } 364 void getMatchStart(RegisterID reg) 365 { 366 ASSERT(!m_pattern.m_body->m_hasFixedSize); 367 if (compileMode == IncludeSubpatterns) 368 load32(output, reg); 369 else 370 move(output, reg); 306 371 } 307 372 … … 1070 1135 JumpList foundEndingNewLine; 1071 1136 1072 if (m_pattern.m_body->m_hasFixedSize) { 1073 move(index, matchPos); 1074 sub32(Imm32(m_checked), matchPos); 1075 } else 1076 load32(Address(output), matchPos); 1137 ASSERT(!m_pattern.m_body->m_hasFixedSize); 1138 getMatchStart(matchPos); 1077 1139 1078 1140 saveStartIndex.append(branchTest32(Zero, matchPos)); … … 1094 1156 op.m_jumps.append(branchTest32(NonZero, matchPos)); 1095 1157 1096 store32(matchPos, Address(output)); 1158 ASSERT(!m_pattern.m_body->m_hasFixedSize); 1159 setMatchStart(matchPos); 1097 1160 1098 1161 move(index, matchPos); … … 1316 1379 1317 1380 // Adjust the stack pointer to remove the pattern's frame. 1318 if (m_pattern.m_body->m_callFrameSize) 1319 addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); 1381 removeCallFrame(); 1320 1382 1321 1383 // Load appropriate values into the return register and the first output … … 1327 1389 if (priorAlternative->m_minimumSize) 1328 1390 sub32(Imm32(priorAlternative->m_minimumSize), returnRegister); 1329 store32(returnRegister, output); 1391 if (compileMode == IncludeSubpatterns) 1392 store32(returnRegister, output); 1330 1393 } else 1331 load32(Address(output), returnRegister); 1332 store32(index, Address(output, 4)); 1394 getMatchStart(returnRegister); 1395 if (compileMode == IncludeSubpatterns) 1396 store32(index, Address(output, 4)); 1397 move(index, returnRegister2); 1398 1333 1399 generateReturn(); 1334 1400 … … 1513 1579 // offsets only afterwards, at the point the results array is 1514 1580 // being accessed. 1515 if (term->capture()) { 1516 int offsetId = term->parentheses.subpatternId << 1; 1581 if (term->capture() && compileMode == IncludeSubpatterns) { 1517 1582 int inputOffset = term->inputPosition - m_checked; 1518 1583 if (term->quantityType == QuantifierFixedCount) … … 1521 1586 move(index, indexTemporary); 1522 1587 add32(Imm32(inputOffset), indexTemporary); 1523 s tore32(indexTemporary, Address(output, offsetId * sizeof(int)));1588 setSubpatternStart(indexTemporary, term->parentheses.subpatternId); 1524 1589 } else 1525 s tore32(index, Address(output, offsetId * sizeof(int)));1590 setSubpatternStart(index, term->parentheses.subpatternId); 1526 1591 } 1527 1592 break; … … 1549 1614 // offsets only afterwards, at the point the results array is 1550 1615 // being accessed. 1551 if (term->capture()) { 1552 int offsetId = (term->parentheses.subpatternId << 1) + 1; 1616 if (term->capture() && compileMode == IncludeSubpatterns) { 1553 1617 int inputOffset = term->inputPosition - m_checked; 1554 1618 if (inputOffset) { 1555 1619 move(index, indexTemporary); 1556 1620 add32(Imm32(inputOffset), indexTemporary); 1557 s tore32(indexTemporary, Address(output, offsetId * sizeof(int)));1621 setSubpatternEnd(indexTemporary, term->parentheses.subpatternId); 1558 1622 } else 1559 s tore32(index, Address(output, offsetId * sizeof(int)));1623 setSubpatternEnd(index, term->parentheses.subpatternId); 1560 1624 } 1561 1625 … … 1647 1711 1648 1712 case OpMatchFailed: 1649 if (m_pattern.m_body->m_callFrameSize)1650 addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);1651 move(TrustedImm32( -1), returnRegister);1713 removeCallFrame(); 1714 move(TrustedImmPtr((void*)WTF::notFound), returnRegister); 1715 move(TrustedImm32(0), returnRegister2); 1652 1716 generateReturn(); 1653 1717 break; … … 1744 1808 if (!m_pattern.m_body->m_hasFixedSize) { 1745 1809 if (alternative->m_minimumSize == 1) 1746 s tore32(index, Address(output));1810 setMatchStart(index); 1747 1811 else { 1748 1812 move(index, regT0); … … 1751 1815 else 1752 1816 add32(TrustedImm32(1), regT0); 1753 s tore32(regT0, Address(output));1817 setMatchStart(regT0); 1754 1818 } 1755 1819 } … … 1837 1901 if (needsToUpdateMatchStart && alternative->m_minimumSize == 1) { 1838 1902 // index is already incremented by 1, so just store it now! 1839 s tore32(index, Address(output));1903 setMatchStart(index); 1840 1904 needsToUpdateMatchStart = false; 1841 1905 } … … 1861 1925 if (needsToUpdateMatchStart) { 1862 1926 if (!m_pattern.m_body->m_minimumSize) 1863 s tore32(index, Address(output));1927 setMatchStart(index); 1864 1928 else { 1865 1929 move(index, regT0); 1866 1930 sub32(Imm32(m_pattern.m_body->m_minimumSize), regT0); 1867 s tore32(regT0, Address(output));1931 setMatchStart(regT0); 1868 1932 } 1869 1933 } … … 1887 1951 matchFailed.link(this); 1888 1952 1889 if (m_pattern.m_body->m_callFrameSize)1890 addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);1891 move(TrustedImm32( -1), returnRegister);1953 removeCallFrame(); 1954 move(TrustedImmPtr((void*)WTF::notFound), returnRegister); 1955 move(TrustedImm32(0), returnRegister2); 1892 1956 generateReturn(); 1893 1957 break; … … 2056 2120 2057 2121 // We only need to backtrack to thispoint if capturing or greedy. 2058 if ( term->capture() || term->quantityType == QuantifierGreedy) {2122 if ((term->capture() && compileMode == IncludeSubpatterns) || term->quantityType == QuantifierGreedy) { 2059 2123 m_backtrackingState.link(this); 2060 2124 2061 2125 // If capturing, clear the capture (we only need to reset start). 2062 if (term->capture() )2063 store32(TrustedImm32(-1), Address(output, (term->parentheses.subpatternId << 1) * sizeof(int)));2126 if (term->capture() && compileMode == IncludeSubpatterns) 2127 clearSubpatternStart(term->parentheses.subpatternId); 2064 2128 2065 2129 // If Greedy, jump to the end. … … 2451 2515 loadPtr(Address(X86Registers::ebp, 3 * sizeof(void*)), index); 2452 2516 loadPtr(Address(X86Registers::ebp, 4 * sizeof(void*)), length); 2453 loadPtr(Address(X86Registers::ebp, 5 * sizeof(void*)), output); 2517 if (compileMode == IncludeSubpatterns) 2518 loadPtr(Address(X86Registers::ebp, 5 * sizeof(void*)), output); 2454 2519 #else 2455 loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); 2520 if (compileMode == IncludeSubpatterns) 2521 loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); 2456 2522 #endif 2457 2523 #elif CPU(ARM) … … 2462 2528 push(ARMRegisters::r8); // scratch register 2463 2529 #endif 2464 move(ARMRegisters::r3, output); 2530 if (compileMode == IncludeSubpatterns) 2531 move(ARMRegisters::r3, output); 2465 2532 #elif CPU(SH4) 2466 2533 push(SH4Registers::r11); … … 2512 2579 2513 2580 Jump hasInput = checkInput(); 2514 move(TrustedImm32(-1), returnRegister); 2581 move(TrustedImmPtr((void*)WTF::notFound), returnRegister); 2582 move(TrustedImm32(0), returnRegister2); 2515 2583 generateReturn(); 2516 2584 hasInput.link(this); 2517 2585 2518 for (unsigned i = 0; i < m_pattern.m_numSubpatterns + 1; ++i) 2519 store32(TrustedImm32(-1), Address(output, (i << 1) * sizeof(int))); 2586 if (compileMode == IncludeSubpatterns) { 2587 for (unsigned i = 0; i < m_pattern.m_numSubpatterns + 1; ++i) 2588 store32(TrustedImm32(-1), Address(output, (i << 1) * sizeof(int))); 2589 } 2520 2590 2521 2591 if (!m_pattern.m_body->m_hasFixedSize) 2522 store32(index, Address(output)); 2523 2524 if (m_pattern.m_body->m_callFrameSize) 2525 subPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister); 2592 setMatchStart(index); 2593 2594 initCallFrame(); 2526 2595 2527 2596 // Compile the pattern to the internal 'YarrOp' representation. … … 2541 2610 LinkBuffer linkBuffer(*globalData, this, REGEXP_CODE_ID); 2542 2611 m_backtrackingState.linkDataLabels(linkBuffer); 2543 if (m_charSize == Char8) 2544 jitObject.set8BitCode(linkBuffer.finalizeCode()); 2545 else 2546 jitObject.set16BitCode(linkBuffer.finalizeCode()); 2612 2613 if (compileMode == MatchOnly) { 2614 if (m_charSize == Char8) 2615 jitObject.set8BitCodeMatchOnly(linkBuffer.finalizeCode()); 2616 else 2617 jitObject.set16BitCodeMatchOnly(linkBuffer.finalizeCode()); 2618 } else { 2619 if (m_charSize == Char8) 2620 jitObject.set8BitCode(linkBuffer.finalizeCode()); 2621 else 2622 jitObject.set16BitCode(linkBuffer.finalizeCode()); 2623 } 2547 2624 jitObject.setFallBack(m_shouldFallBack); 2548 2625 } … … 2578 2655 }; 2579 2656 2580 void jitCompile(YarrPattern& pattern, YarrCharSize charSize, JSGlobalData* globalData, YarrCodeBlock& jitObject )2657 void jitCompile(YarrPattern& pattern, YarrCharSize charSize, JSGlobalData* globalData, YarrCodeBlock& jitObject, YarrJITCompileMode mode) 2581 2658 { 2582 YarrGenerator(pattern, charSize).compile(globalData, jitObject); 2659 if (mode == MatchOnly) 2660 YarrGenerator<MatchOnly>(pattern, charSize).compile(globalData, jitObject); 2661 else 2662 YarrGenerator<IncludeSubpatterns>(pattern, charSize).compile(globalData, jitObject); 2583 2663 } 2584 2664 -
trunk/Source/JavaScriptCore/yarr/YarrJIT.h
r103641 r112454 30 30 31 31 #include "JSGlobalData.h" 32 #include "MacroAssembler.h" 32 #include "MacroAssemblerCodeRef.h" 33 #include "MatchResult.h" 33 34 #include "UString.h" 34 35 #include "Yarr.h" … … 49 50 50 51 class YarrCodeBlock { 51 typedef int (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL; 52 typedef int (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL; 52 #if CPU(X86_64) 53 typedef MatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL; 54 typedef MatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL; 55 typedef MatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length) YARR_CALL; 56 typedef MatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length) YARR_CALL; 57 #else 58 typedef EncodedMatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL; 59 typedef EncodedMatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL; 60 typedef EncodedMatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length) YARR_CALL; 61 typedef EncodedMatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length) YARR_CALL; 62 #endif 53 63 54 64 public: … … 64 74 void setFallBack(bool fallback) { m_needFallBack = fallback; } 65 75 bool isFallBack() { return m_needFallBack; } 76 66 77 bool has8BitCode() { return m_ref8.size(); } 67 78 bool has16BitCode() { return m_ref16.size(); } 68 void set8BitCode(MacroAssembler ::CodeRef ref) { m_ref8 = ref; }69 void set16BitCode(MacroAssembler ::CodeRef ref) { m_ref16 = ref; }79 void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; } 80 void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; } 70 81 71 int execute(const LChar* input, unsigned start, unsigned length, int* output) 82 bool has8BitCodeMatchOnly() { return m_matchOnly8.size(); } 83 bool has16BitCodeMatchOnly() { return m_matchOnly16.size(); } 84 void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; } 85 void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; } 86 87 MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output) 72 88 { 73 89 ASSERT(has8BitCode()); 74 return reinterpret_cast<YarrJITCode8>(m_ref8.code().executableAddress())(input, start, length, output);90 return MatchResult(reinterpret_cast<YarrJITCode8>(m_ref8.code().executableAddress())(input, start, length, output)); 75 91 } 76 92 77 int execute(const UChar* input, unsigned start, unsigned length, int* output)93 MatchResult execute(const UChar* input, unsigned start, unsigned length, int* output) 78 94 { 79 95 ASSERT(has16BitCode()); 80 return reinterpret_cast<YarrJITCode16>(m_ref16.code().executableAddress())(input, start, length, output);96 return MatchResult(reinterpret_cast<YarrJITCode16>(m_ref16.code().executableAddress())(input, start, length, output)); 81 97 } 98 99 MatchResult execute(const LChar* input, unsigned start, unsigned length) 100 { 101 ASSERT(has8BitCodeMatchOnly()); 102 return MatchResult(reinterpret_cast<YarrJITCodeMatchOnly8>(m_matchOnly8.code().executableAddress())(input, start, length)); 103 } 104 105 MatchResult execute(const UChar* input, unsigned start, unsigned length) 106 { 107 ASSERT(has16BitCodeMatchOnly()); 108 return MatchResult(reinterpret_cast<YarrJITCodeMatchOnly16>(m_matchOnly16.code().executableAddress())(input, start, length)); 109 } 110 82 111 #if ENABLE(REGEXP_TRACING) 83 112 void *getAddr() { return m_ref.code().executableAddress(); } 84 113 #endif 85 114 115 void clear() 116 { 117 m_ref8 = MacroAssemblerCodeRef(); 118 m_ref16 = MacroAssemblerCodeRef(); 119 m_matchOnly8 = MacroAssemblerCodeRef(); 120 m_matchOnly16 = MacroAssemblerCodeRef(); 121 m_needFallBack = false; 122 } 123 86 124 private: 87 MacroAssembler::CodeRef m_ref8; 88 MacroAssembler::CodeRef m_ref16; 125 MacroAssemblerCodeRef m_ref8; 126 MacroAssemblerCodeRef m_ref16; 127 MacroAssemblerCodeRef m_matchOnly8; 128 MacroAssemblerCodeRef m_matchOnly16; 89 129 bool m_needFallBack; 90 130 }; 91 131 92 void jitCompile(YarrPattern&, YarrCharSize, JSGlobalData*, YarrCodeBlock& jitObject); 93 94 inline int execute(YarrCodeBlock& jitObject, const LChar* input, unsigned start, unsigned length, int* output) 95 { 96 return jitObject.execute(input, start, length, output); 97 } 98 99 inline int execute(YarrCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output) 100 { 101 return jitObject.execute(input, start, length, output); 102 } 132 enum YarrJITCompileMode { 133 MatchOnly, 134 IncludeSubpatterns 135 }; 136 void jitCompile(YarrPattern&, YarrCharSize, JSGlobalData*, YarrCodeBlock& jitObject, YarrJITCompileMode = IncludeSubpatterns); 103 137 104 138 } } // namespace JSC::Yarr
Note:
See TracChangeset
for help on using the changeset viewer.