Changeset 185719 in webkit
- Timestamp:
- Jun 18, 2015, 1:29:37 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
cssjit/SelectorCompiler.cpp (modified) (10 diffs)
-
cssjit/StackAllocator.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r185717 r185719 1 2015-06-18 Benjamin Poulain <bpoulain@apple.com> 2 3 [CSS JIT][ARMv7] The pseudo element early exit trashes r6 4 https://bugs.webkit.org/show_bug.cgi?id=146078 5 6 Reviewed by Alex Christensen. 7 8 The pseudo element early failure runs before we generate the prologue. 9 The reason is that we can often exit immediately on function entry, before 10 we even touch any memory. 11 12 On ARMv7, we don't have many spare registers so the MacroAssembler 13 uses r6 as a scratch register and the client code is expected to save 14 it. 15 16 In the early failure case, we were not pushing r6 before using the MacroAssembler 17 and its value could be trashed. 18 19 This patch push the macro assembler registers separately from the prologue. 20 21 For restoring the registers, a new function generateFunctionEnding() encapsulate 22 the pop() and ret(). 23 24 * cssjit/SelectorCompiler.cpp: 25 (WebCore::SelectorCompiler::SelectorCodeGenerator::pushMacroAssemblerRegisters): 26 (WebCore::SelectorCompiler::SelectorCodeGenerator::popMacroAssemblerRegisters): 27 (WebCore::SelectorCompiler::SelectorCodeGenerator::generatePrologue): 28 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateEpilogue): 29 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker): 30 31 * cssjit/StackAllocator.h: 32 (WebCore::StackAllocator::operator=): 33 We have a new case for the stack allocator: some stack changes are conditional 34 at compile time instead of runtime. This is easy to deal with by overriding 35 the stack if a path is not taken at compile time. 36 1 37 2015-06-17 Conrad Shultz <conrad_shultz@apple.com> 2 38 -
trunk/Source/WebCore/cssjit/SelectorCompiler.cpp
r185071 r185719 341 341 void moduloIsZero(Assembler::JumpList& failureCases, Assembler::RegisterID inputDividend, int divisor); 342 342 343 void pushMacroAssemblerRegisters(); 344 void popMacroAssemblerRegisters(StackAllocator&); 343 345 bool generatePrologue(); 344 void generateEpilogue(); 346 void generateEpilogue(StackAllocator&); 347 StackAllocator::StackReferenceVector m_macroAssemblerRegistersStackReferences; 345 348 StackAllocator::StackReferenceVector m_prologueStackReferences; 346 349 … … 1680 1683 } 1681 1684 1685 inline void SelectorCodeGenerator::pushMacroAssemblerRegisters() 1686 { 1687 #if CPU(ARM_THUMB2) 1688 // r6 is tempRegister in RegisterAllocator.h and addressTempRegister in MacroAssemblerARMv7.h and must be preserved by the callee. 1689 Vector<JSC::MacroAssembler::RegisterID, 1> macroAssemblerRegisters({ JSC::ARMRegisters::r6 }); 1690 m_macroAssemblerRegistersStackReferences = m_stackAllocator.push(macroAssemblerRegisters); 1691 #endif 1692 } 1693 1694 inline void SelectorCodeGenerator::popMacroAssemblerRegisters(StackAllocator& stackAllocator) 1695 { 1696 #if CPU(ARM_THUMB2) 1697 Vector<JSC::MacroAssembler::RegisterID, 1> macroAssemblerRegisters({ JSC::ARMRegisters::r6 }); 1698 stackAllocator.pop(m_macroAssemblerRegistersStackReferences, macroAssemblerRegisters); 1699 #else 1700 UNUSED_PARAM(stackAllocator); 1701 #endif 1702 } 1703 1682 1704 inline bool SelectorCodeGenerator::generatePrologue() 1683 1705 { … … 1689 1711 return true; 1690 1712 #elif CPU(ARM_THUMB2) 1691 Vector<JSC::MacroAssembler::RegisterID, 2> prologueRegisters;1713 Vector<JSC::MacroAssembler::RegisterID, 1> prologueRegisters; 1692 1714 prologueRegisters.append(JSC::ARMRegisters::lr); 1693 // r6 is tempRegister in RegisterAllocator.h and addressTempRegister in MacroAssemblerARMv7.h and must be preserved by the callee.1694 prologueRegisters.append(JSC::ARMRegisters::r6);1695 1715 m_prologueStackReferences = m_stackAllocator.push(prologueRegisters); 1696 1716 return true; … … 1704 1724 } 1705 1725 1706 inline void SelectorCodeGenerator::generateEpilogue( )1726 inline void SelectorCodeGenerator::generateEpilogue(StackAllocator& stackAllocator) 1707 1727 { 1708 1728 #if CPU(ARM64) 1709 Vector<JSC::MacroAssembler::RegisterID, 2> prologueRegisters; 1710 prologueRegisters.append(JSC::ARM64Registers::lr); 1711 prologueRegisters.append(JSC::ARM64Registers::fp); 1712 m_stackAllocator.pop(m_prologueStackReferences, prologueRegisters); 1729 Vector<JSC::MacroAssembler::RegisterID, 2> prologueRegisters({ JSC::ARM64Registers::lr, JSC::ARM64Registers::fp }); 1730 stackAllocator.pop(m_prologueStackReferences, prologueRegisters); 1713 1731 #elif CPU(ARM_THUMB2) 1714 Vector<JSC::MacroAssembler::RegisterID, 2> prologueRegisters; 1715 prologueRegisters.append(JSC::ARMRegisters::lr); 1716 prologueRegisters.append(JSC::ARMRegisters::r6); 1717 m_stackAllocator.pop(m_prologueStackReferences, prologueRegisters); 1732 Vector<JSC::MacroAssembler::RegisterID, 1> prologueRegister({ JSC::ARMRegisters::lr }); 1733 stackAllocator.pop(m_prologueStackReferences, prologueRegister); 1718 1734 #elif CPU(X86_64) && CSS_SELECTOR_JIT_DEBUGGING 1719 Vector<JSC::MacroAssembler::RegisterID, 1> prologueRegister; 1720 prologueRegister.append(callFrameRegister); 1721 m_stackAllocator.pop(m_prologueStackReferences, prologueRegister); 1735 Vector<JSC::MacroAssembler::RegisterID, 1> prologueRegister({ callFrameRegister }); 1736 stackAllocator.pop(m_prologueStackReferences, prologueRegister); 1737 #else 1738 UNUSED_PARAM(stackAllocator); 1722 1739 #endif 1723 1740 } … … 1735 1752 void SelectorCodeGenerator::generateSelectorChecker() 1736 1753 { 1754 pushMacroAssemblerRegisters(); 1755 StackAllocator earlyFailureStack = m_stackAllocator; 1756 1737 1757 Assembler::JumpList failureOnFunctionEntry; 1738 1758 // Test selector's pseudo element equals to requested PseudoId. … … 1761 1781 if (m_selectorFragments.stackRequirements > maximumBacktrackingAllocations) { 1762 1782 m_assembler.move(Assembler::TrustedImm32(0), returnRegister); 1783 popMacroAssemblerRegisters(m_stackAllocator); 1763 1784 m_assembler.ret(); 1764 1785 return; … … 1819 1840 if (m_functionType == FunctionType::SimpleSelectorChecker) { 1820 1841 if (temporaryStackBase == m_stackAllocator.stackTop() && !reservedCalleeSavedRegisters && !needsEpilogue) { 1842 StackAllocator successStack = m_stackAllocator; 1843 StackAllocator failureStack = m_stackAllocator; 1844 1821 1845 ASSERT(!m_selectorFragments.stackRequirements); 1822 1846 // Success. 1823 1847 m_assembler.move(Assembler::TrustedImm32(1), returnRegister); 1848 popMacroAssemblerRegisters(successStack); 1824 1849 m_assembler.ret(); 1825 1850 … … 1829 1854 failureCases.link(&m_assembler); 1830 1855 m_assembler.move(Assembler::TrustedImm32(0), returnRegister); 1856 popMacroAssemblerRegisters(failureStack); 1831 1857 m_assembler.ret(); 1832 } 1858 } else 1859 failureStack = successStack; 1860 1861 m_stackAllocator.merge(WTF::move(successStack), WTF::move(failureStack)); 1833 1862 return; 1834 1863 } … … 1850 1879 if (reservedCalleeSavedRegisters) 1851 1880 m_stackAllocator.pop(calleeSavedRegisterStackReferences, m_registerAllocator.restoreCalleeSavedRegisters()); 1881 1882 StackAllocator successStack = m_stackAllocator; 1852 1883 if (needsEpilogue) 1853 generateEpilogue(); 1884 generateEpilogue(successStack); 1885 popMacroAssemblerRegisters(successStack); 1854 1886 m_assembler.ret(); 1855 1887 … … 1858 1890 failureOnFunctionEntry.link(&m_assembler); 1859 1891 m_assembler.move(Assembler::TrustedImm32(0), returnRegister); 1892 popMacroAssemblerRegisters(earlyFailureStack); 1860 1893 m_assembler.ret(); 1861 } 1894 } else 1895 earlyFailureStack = successStack; 1896 m_stackAllocator.merge(WTF::move(successStack), WTF::move(earlyFailureStack)); 1862 1897 } 1863 1898 -
trunk/Source/WebCore/cssjit/StackAllocator.h
r183065 r185719 240 240 } 241 241 242 StackAllocator& operator=(const StackAllocator& other) 243 { 244 RELEASE_ASSERT(&m_assembler == &other.m_assembler); 245 m_offsetFromTop = other.m_offsetFromTop; 246 m_hasFunctionCallPadding = other.m_hasFunctionCallPadding; 247 return *this; 248 } 249 250 242 251 private: 243 252 static unsigned stackUnitInBytes()
Note:
See TracChangeset
for help on using the changeset viewer.