Changeset 94559 in webkit for trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
- Timestamp:
- Sep 6, 2011, 2:23:55 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r94477 r94559 1402 1402 } 1403 1403 1404 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor )1404 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor, PassOwnPtr<CodeBlock> alternative) 1405 1405 : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject) 1406 1406 , m_heap(&m_globalObject->globalData().heap) 1407 , m_executeCounter(-1000) // trigger optimization when sign bit clears 1407 1408 , m_numCalleeRegisters(0) 1408 1409 , m_numVars(0) … … 1423 1424 , m_sourceOffset(sourceOffset) 1424 1425 , m_symbolTable(symTab) 1426 , m_alternative(alternative) 1425 1427 { 1426 1428 ASSERT(m_source); … … 1442 1444 } else 1443 1445 fprintf(stderr, " bc = %d: ", profile->bytecodeOffset); 1444 fprintf(stderr, 1445 "samples = %u, int32 = %u, double = %u, cell = %u, array = %u\n", 1446 profile->numberOfSamples(), 1447 profile->probabilityOfInt32(), 1448 profile->probabilityOfDouble(), 1449 profile->probabilityOfCell(), 1450 profile->probabilityOfArray()); 1451 } 1452 #endif 1446 profile->dump(stderr); 1447 fprintf(stderr, "\n"); 1448 } 1449 #endif 1450 1451 // We should not be garbage collected if there are incoming calls. But 1452 // if this is called during heap destruction, then there may still be 1453 // incoming calls, which is harmless. 1454 1455 // Note that our outgoing calls will be removed from other CodeBlocks' 1456 // m_incomingCalls linked lists through the execution of the ~CallLinkInfo 1457 // destructors. 1453 1458 1454 1459 #if ENABLE(JIT) … … 1520 1525 bool handleWeakReferences = false; 1521 1526 1527 if (!!m_alternative) 1528 m_alternative->visitAggregate(visitor); 1522 1529 visitor.append(&m_globalObject); 1523 1530 visitor.append(&m_ownerExecutable); … … 1790 1797 1791 1798 #if ENABLE(JIT) 1799 void CallLinkInfo::unlink(JSGlobalData& globalData, RepatchBuffer& repatchBuffer) 1800 { 1801 ASSERT(isLinked()); 1802 1803 if (isDFG) { 1804 #if ENABLE(DFG_JIT) 1805 repatchBuffer.relink(CodeLocationCall(callReturnLocation), isCall ? operationLinkCall : operationLinkConstruct); 1806 #else 1807 ASSERT_NOT_REACHED(); 1808 #endif 1809 } else 1810 repatchBuffer.relink(CodeLocationNearCall(callReturnLocation), isCall? globalData.jitStubs->ctiVirtualCallLink() : globalData.jitStubs->ctiVirtualConstructLink()); 1811 hasSeenShouldRepatch = false; 1812 callee.clear(); 1813 1814 // It will be on a list if the callee has a code block. 1815 if (isOnList()) 1816 remove(); 1817 } 1818 1792 1819 void CodeBlock::unlinkCalls() 1793 1820 { 1821 if (!!m_alternative) 1822 m_alternative->unlinkCalls(); 1794 1823 if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size())) 1795 1824 return; … … 1800 1829 if (!m_callLinkInfos[i].isLinked()) 1801 1830 continue; 1802 if (getJITCode().jitType() == JITCode::DFGJIT) { 1803 #if ENABLE(DFG_JIT) 1804 repatchBuffer.relink(CodeLocationCall(m_callLinkInfos[i].callReturnLocation), m_callLinkInfos[i].isCall ? operationLinkCall : operationLinkConstruct); 1805 #else 1806 ASSERT_NOT_REACHED(); 1807 #endif 1808 } else 1809 repatchBuffer.relink(CodeLocationNearCall(m_callLinkInfos[i].callReturnLocation), m_callLinkInfos[i].isCall ? m_globalData->jitStubs->ctiVirtualCallLink() : m_globalData->jitStubs->ctiVirtualConstructLink()); 1810 m_callLinkInfos[i].unlink(); 1811 } 1831 m_callLinkInfos[i].unlink(*m_globalData, repatchBuffer); 1832 } 1833 } 1834 1835 void CodeBlock::unlinkIncomingCalls() 1836 { 1837 RepatchBuffer repatchBuffer(this); 1838 while (m_incomingCalls.begin() != m_incomingCalls.end()) 1839 m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer); 1812 1840 } 1813 1841 #endif … … 1815 1843 void CodeBlock::clearEvalCache() 1816 1844 { 1845 if (!!m_alternative) 1846 m_alternative->clearEvalCache(); 1817 1847 if (!m_rareData) 1818 1848 return; … … 1820 1850 } 1821 1851 1852 template<typename T> 1853 inline void replaceExistingEntries(Vector<T>& target, Vector<T>& source) 1854 { 1855 ASSERT(target.size() <= source.size()); 1856 for (size_t i = 0; i < target.size(); ++i) 1857 target[i] = source[i]; 1858 } 1859 1860 void CodeBlock::copyDataFromAlternative() 1861 { 1862 if (!m_alternative) 1863 return; 1864 1865 replaceExistingEntries(m_constantRegisters, m_alternative->m_constantRegisters); 1866 replaceExistingEntries(m_functionDecls, m_alternative->m_functionDecls); 1867 replaceExistingEntries(m_functionExprs, m_alternative->m_functionExprs); 1868 } 1869 1870 // FIXME: Implement OSR. If compileOptimized() is called from somewhere other than the 1871 // epilogue, do OSR from the old code block to the new one. 1872 1873 // FIXME: After doing successful optimized compilation, reset the profiling counter to -1, so 1874 // that the next execution of the old code block will jump straight into compileOptimized() 1875 // and perform OSR. 1876 1877 // FIXME: Ensure that a call to compileOptimized() just does OSR (and resets the counter to -1) 1878 // if the code had already been compiled. 1879 1880 CodeBlock* ProgramCodeBlock::replacement() 1881 { 1882 return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode(); 1883 } 1884 1885 CodeBlock* EvalCodeBlock::replacement() 1886 { 1887 return &static_cast<EvalExecutable*>(ownerExecutable())->generatedBytecode(); 1888 } 1889 1890 CodeBlock* FunctionCodeBlock::replacement() 1891 { 1892 return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall); 1893 } 1894 1895 JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode) 1896 { 1897 if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) { 1898 // No OSR yet, so make sure we don't hit this again anytime soon. 1899 dontOptimizeAnytimeSoon(); 1900 return 0; 1901 } 1902 JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scopeChainNode); 1903 return error; 1904 } 1905 1906 JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode) 1907 { 1908 if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) { 1909 // No OSR yet, so make sure we don't hit this again anytime soon. 1910 dontOptimizeAnytimeSoon(); 1911 return 0; 1912 } 1913 JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scopeChainNode); 1914 return error; 1915 } 1916 1917 JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode) 1918 { 1919 if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) { 1920 // No OSR yet, so make sure we don't hit this again anytime soon. 1921 dontOptimizeAnytimeSoon(); 1922 return 0; 1923 } 1924 JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scopeChainNode, m_isConstructor ? CodeForConstruct : CodeForCall); 1925 return error; 1926 } 1927 1822 1928 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.