Changeset 176836 in webkit for trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
- Timestamp:
- Dec 4, 2014, 9:58:07 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r176479 r176836 31 31 #include "CodeBlock.h" 32 32 33 #include "BasicBlockLocation.h" 33 34 #include "BytecodeGenerator.h" 34 35 #include "BytecodeUseDef.h" … … 851 852 break; 852 853 } 854 case op_profile_control_flow: { 855 BasicBlockLocation* basicBlockLocation = (++it)->u.basicBlockLocation; 856 printLocationAndOp(out, exec, location, it, "profile_control_flow"); 857 out.printf("[%d, %d]", basicBlockLocation->startOffset(), basicBlockLocation->endOffset()); 858 break; 859 } 853 860 case op_not: { 854 861 printUnaryOp(out, exec, location, it, "not"); … … 1729 1736 setNumParameters(unlinkedCodeBlock->numParameters()); 1730 1737 1731 if (vm()->typeProfiler() )1732 vm()-> typeProfiler()->functionHasExecutedCache()->removeUnexecutedRange(m_ownerExecutable->sourceID(), m_ownerExecutable->typeProfilingStartOffset(), m_ownerExecutable->typeProfilingEndOffset());1738 if (vm()->typeProfiler() || vm()->controlFlowProfiler()) 1739 vm()->functionHasExecutedCache()->removeUnexecutedRange(m_ownerExecutable->sourceID(), m_ownerExecutable->typeProfilingStartOffset(), m_ownerExecutable->typeProfilingEndOffset()); 1733 1740 1734 1741 setConstantRegisters(unlinkedCodeBlock->constantRegisters()); … … 1738 1745 for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) { 1739 1746 UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i); 1740 if (vm()->typeProfiler() )1741 vm()-> typeProfiler()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());1747 if (vm()->typeProfiler() || vm()->controlFlowProfiler()) 1748 vm()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset()); 1742 1749 unsigned lineCount = unlinkedExecutable->lineCount(); 1743 1750 unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset(); … … 1756 1763 for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) { 1757 1764 UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i); 1758 if (vm()->typeProfiler() )1759 vm()-> typeProfiler()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());1765 if (vm()->typeProfiler() || vm()->controlFlowProfiler()) 1766 vm()->functionHasExecutedCache()->insertUnexecutedRange(m_ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset()); 1760 1767 unsigned lineCount = unlinkedExecutable->lineCount(); 1761 1768 unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset(); … … 2126 2133 i += opLength; 2127 2134 } 2135 2136 if (vm()->controlFlowProfiler()) { 2137 const Vector<size_t>& bytecodeOffsets = unlinkedCodeBlock->opProfileControlFlowBytecodeOffsets(); 2138 for (size_t i = 0, offsetsLength = bytecodeOffsets.size(); i < offsetsLength; i++) { 2139 // Because op_profile_control_flow is emitted at the beginning of every basic block, finding 2140 // the next op_profile_control_flow will give us the text range of a single basic block. 2141 size_t startIdx = bytecodeOffsets[i]; 2142 RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[startIdx].u.opcode) == op_profile_control_flow); 2143 int basicBlockStartOffset = instructions[startIdx + 1].u.operand; 2144 int basicBlockEndOffset; 2145 if (i + 1 < offsetsLength) { 2146 size_t endIdx = bytecodeOffsets[i + 1]; 2147 RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[endIdx].u.opcode) == op_profile_control_flow); 2148 basicBlockEndOffset = instructions[endIdx + 1].u.operand; 2149 } else 2150 basicBlockEndOffset = m_sourceOffset + m_ownerExecutable->source().length() - 1; 2151 2152 BasicBlockLocation* basicBlockLocation = vm()->controlFlowProfiler()->getBasicBlockLocation(m_ownerExecutable->sourceID(), basicBlockStartOffset, basicBlockEndOffset); 2153 2154 // Find all functions that are enclosed within the range: [basicBlockStartOffset, basicBlockEndOffset] 2155 // and insert these functions' start/end offsets as gaps in the current BasicBlockLocation. 2156 // This is necessary because in the original source text of a JavaScript program, 2157 // function literals form new basic blocks boundaries, but they aren't represented 2158 // inside the CodeBlock's instruction stream. 2159 auto insertFunctionGaps = [basicBlockLocation, basicBlockStartOffset, basicBlockEndOffset] (const WriteBarrier<FunctionExecutable>& functionExecutable) { 2160 const UnlinkedFunctionExecutable* executable = functionExecutable->unlinkedExecutable(); 2161 int functionStart = executable->typeProfilingStartOffset(); 2162 int functionEnd = executable->typeProfilingEndOffset(); 2163 if (functionStart >= basicBlockStartOffset && functionEnd <= basicBlockEndOffset) 2164 basicBlockLocation->insertGap(functionStart, functionEnd); 2165 }; 2166 2167 for (const WriteBarrier<FunctionExecutable>& executable : m_functionDecls) 2168 insertFunctionGaps(executable); 2169 for (const WriteBarrier<FunctionExecutable>& executable : m_functionExprs) 2170 insertFunctionGaps(executable); 2171 2172 instructions[startIdx + 1].u.basicBlockLocation = basicBlockLocation; 2173 } 2174 } 2175 2128 2176 m_instructions = WTF::RefCountedArray<Instruction>(instructions); 2129 2177
Note:
See TracChangeset
for help on using the changeset viewer.