Changeset 244811 in webkit
- Timestamp:
- Apr 30, 2019, 4:37:27 PM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r244806 r244811 1 2019-04-30 Saam barati <[email protected]> 2 3 CodeBlock::m_instructionCount is wrong 4 https://bugs.webkit.org/show_bug.cgi?id=197304 5 6 Reviewed by Yusuke Suzuki. 7 8 What we were calling instructionCount() was wrong, as evidenced by 9 us using it incorrectly both in the sampling profiler and when we 10 dumped bytecode for a given CodeBlock. Prior to the bytecode rewrite, 11 instructionCount() was probably valid to do bounds checks against. 12 However, this is no longer the case. This patch renames what we called 13 instructionCount() to bytecodeCost(). It is now only used to make decisions 14 about inlining and tier up heuristics. I've also named options related to 15 this appropriately. 16 17 This patch also introduces instructionsSize(). The result of this method 18 is valid to do bounds checks against. 19 20 * bytecode/CodeBlock.cpp: 21 (JSC::CodeBlock::dumpAssumingJITType const): 22 (JSC::CodeBlock::CodeBlock): 23 (JSC::CodeBlock::finishCreation): 24 (JSC::CodeBlock::optimizationThresholdScalingFactor): 25 (JSC::CodeBlock::predictedMachineCodeSize): 26 * bytecode/CodeBlock.h: 27 (JSC::CodeBlock::instructionsSize const): 28 (JSC::CodeBlock::bytecodeCost const): 29 (JSC::CodeBlock::instructionCount const): Deleted. 30 * dfg/DFGByteCodeParser.cpp: 31 (JSC::DFG::ByteCodeParser::inliningCost): 32 (JSC::DFG::ByteCodeParser::getInliningBalance): 33 * dfg/DFGCapabilities.cpp: 34 (JSC::DFG::mightCompileEval): 35 (JSC::DFG::mightCompileProgram): 36 (JSC::DFG::mightCompileFunctionForCall): 37 (JSC::DFG::mightCompileFunctionForConstruct): 38 (JSC::DFG::mightInlineFunctionForCall): 39 (JSC::DFG::mightInlineFunctionForClosureCall): 40 (JSC::DFG::mightInlineFunctionForConstruct): 41 * dfg/DFGCapabilities.h: 42 (JSC::DFG::isSmallEnoughToInlineCodeInto): 43 * dfg/DFGDisassembler.cpp: 44 (JSC::DFG::Disassembler::dumpHeader): 45 * dfg/DFGDriver.cpp: 46 (JSC::DFG::compileImpl): 47 * dfg/DFGPlan.cpp: 48 (JSC::DFG::Plan::compileInThread): 49 * dfg/DFGTierUpCheckInjectionPhase.cpp: 50 (JSC::DFG::TierUpCheckInjectionPhase::run): 51 * ftl/FTLCapabilities.cpp: 52 (JSC::FTL::canCompile): 53 * ftl/FTLCompile.cpp: 54 (JSC::FTL::compile): 55 * ftl/FTLLink.cpp: 56 (JSC::FTL::link): 57 * jit/JIT.cpp: 58 (JSC::JIT::link): 59 * jit/JITDisassembler.cpp: 60 (JSC::JITDisassembler::dumpHeader): 61 * llint/LLIntSlowPaths.cpp: 62 (JSC::LLInt::shouldJIT): 63 * profiler/ProfilerBytecodes.cpp: 64 (JSC::Profiler::Bytecodes::Bytecodes): 65 * runtime/Options.h: 66 * runtime/SamplingProfiler.cpp: 67 (JSC::tryGetBytecodeIndex): 68 (JSC::SamplingProfiler::processUnverifiedStackTraces): 69 1 70 2019-04-30 Tadeu Zagallo <[email protected]> 2 71 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r244764 r244811 191 191 if (codeType() == FunctionCode) 192 192 out.print(specializationKind()); 193 out.print(", ", instruction Count());193 out.print(", ", instructionsSize()); 194 194 if (this->jitType() == JITType::BaselineJIT && m_shouldAlwaysBeInlined) 195 195 out.print(" (ShouldAlwaysBeInlined)"); … … 299 299 , m_steppingMode(SteppingModeDisabled) 300 300 , m_numBreakpoints(0) 301 , m_ instructionCount(other.m_instructionCount)301 , m_bytecodeCost(other.m_bytecodeCost) 302 302 , m_scopeRegister(other.m_scopeRegister) 303 303 , m_hash(other.m_hash) … … 525 525 for (const auto& instruction : instructionStream) { 526 526 OpcodeID opcodeID = instruction->opcodeID(); 527 m_ instructionCount += opcodeLengths[opcodeID];527 m_bytecodeCost += opcodeLengths[opcodeID]; 528 528 switch (opcodeID) { 529 529 LINK(OpHasIndexedProperty, arrayProfile) … … 2336 2336 const double d = 0.825914; 2337 2337 2338 double instructionCount = this->instructionCount();2339 2340 ASSERT( instructionCount); // Make sure this is called only after we have an instruction stream; otherwise it'll just return the value of d, which makes no sense.2341 2342 double result = d + a * sqrt( instructionCount + b) + c * instructionCount;2338 double bytecodeCost = this->bytecodeCost(); 2339 2340 ASSERT(bytecodeCost); // Make sure this is called only after we have an instruction stream; otherwise it'll just return the value of d, which makes no sense. 2341 2342 double result = d + a * sqrt(bytecodeCost + b) + c * bytecodeCost; 2343 2343 2344 2344 result *= codeTypeThresholdMultiplier(); … … 2346 2346 if (Options::verboseOSR()) { 2347 2347 dataLog( 2348 *this, ": instruction count is ", instructionCount,2348 *this, ": bytecode cost is ", bytecodeCost, 2349 2349 ", scaling execution counter by ", result, " * ", codeTypeThresholdMultiplier(), 2350 2350 "\n"); … … 2871 2871 return 0; 2872 2872 2873 double doubleResult = multiplier * instructionCount();2873 double doubleResult = multiplier * bytecodeCost(); 2874 2874 2875 2875 // Be even more paranoid: silently reject values that won't fit into a size_t. If -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r244764 r244811 385 385 size_t predictedMachineCodeSize(); 386 386 387 unsigned instructionCount() const { return m_instructionCount; } 387 unsigned instructionsSize() const { return instructions().size(); } 388 unsigned bytecodeCost() const { return m_bytecodeCost; } 388 389 389 390 // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind()) … … 964 965 }; 965 966 }; 966 unsigned m_ instructionCount { 0 };967 unsigned m_bytecodeCost { 0 }; 967 968 VirtualRegister m_scopeRegister; 968 969 mutable CodeBlockHash m_hash; -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r244764 r244811 1560 1560 1561 1561 // It might be possible to inline. 1562 return codeBlock-> instructionCount();1562 return codeBlock->bytecodeCost(); 1563 1563 } 1564 1564 … … 1905 1905 unsigned ByteCodeParser::getInliningBalance(const CallLinkStatus& callLinkStatus, CodeSpecializationKind specializationKind) 1906 1906 { 1907 unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidate InstructionCount();1907 unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidateBytecodeCost(); 1908 1908 if (specializationKind == CodeForConstruct) 1909 inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidate InstructionCount());1909 inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidateBytecoodeCost()); 1910 1910 if (callLinkStatus.isClosureCall()) 1911 inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidate InstructionCount());1911 inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidateBytecodeCost()); 1912 1912 return inliningBalance; 1913 1913 } -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r244505 r244811 50 50 { 51 51 return isSupported() 52 && codeBlock-> instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()52 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost() 53 53 && codeBlock->ownerExecutable()->isOkToOptimize(); 54 54 } … … 56 56 { 57 57 return isSupported() 58 && codeBlock-> instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()58 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost() 59 59 && codeBlock->ownerExecutable()->isOkToOptimize(); 60 60 } … … 62 62 { 63 63 return isSupported() 64 && codeBlock-> instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()64 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost() 65 65 && codeBlock->ownerExecutable()->isOkToOptimize(); 66 66 } … … 68 68 { 69 69 return isSupported() 70 && codeBlock-> instructionCount() <= Options::maximumOptimizationCandidateInstructionCount()70 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost() 71 71 && codeBlock->ownerExecutable()->isOkToOptimize(); 72 72 } … … 74 74 bool mightInlineFunctionForCall(CodeBlock* codeBlock) 75 75 { 76 return codeBlock-> instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()76 return codeBlock->bytecodeCost() <= Options::maximumFunctionForCallInlineCandidateBytecodeCost() 77 77 && isSupportedForInlining(codeBlock); 78 78 } 79 79 bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock) 80 80 { 81 return codeBlock-> instructionCount() <= Options::maximumFunctionForClosureCallInlineCandidateInstructionCount()81 return codeBlock->bytecodeCost() <= Options::maximumFunctionForClosureCallInlineCandidateBytecodeCost() 82 82 && isSupportedForInlining(codeBlock); 83 83 } 84 84 bool mightInlineFunctionForConstruct(CodeBlock* codeBlock) 85 85 { 86 return codeBlock-> instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()86 return codeBlock->bytecodeCost() <= Options::maximumFunctionForConstructInlineCandidateBytecoodeCost() 87 87 && isSupportedForInlining(codeBlock); 88 88 } -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h
r237547 r244811 167 167 inline bool isSmallEnoughToInlineCodeInto(CodeBlock* codeBlock) 168 168 { 169 return codeBlock-> instructionCount() <= Options::maximumInliningCallerSize();169 return codeBlock->bytecodeCost() <= Options::maximumInliningCallerBytecodeCost(); 170 170 } 171 171 -
trunk/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
r244764 r244811 75 75 void Disassembler::dumpHeader(PrintStream& out, LinkBuffer& linkBuffer) 76 76 { 77 out.print("Generated DFG JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITType::DFGJIT), ", instruction count = ", m_graph.m_codeBlock->instructionCount(), ":\n");77 out.print("Generated DFG JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITType::DFGJIT), ", instructions size = ", m_graph.m_codeBlock->instructionsSize(), ":\n"); 78 78 out.print(" Optimized with execution counter = ", m_graph.m_profiledBlock->jitExecuteCounter(), "\n"); 79 79 out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.size()), "):\n"); -
trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp
r244764 r244811 74 74 Ref<DeferredCompilationCallback>&& callback) 75 75 { 76 if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instruction Count())76 if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionsSize()) 77 77 || !ensureGlobalDFGWhitelist().contains(codeBlock)) 78 78 return CompilationFailed; … … 86 86 87 87 if (logCompilationChanges(mode)) 88 dataLog("DFG(Driver) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n");88 dataLog("DFG(Driver) compiling ", *codeBlock, " with ", mode, ", instructions size = ", codeBlock->instructionsSize(), "\n"); 89 89 90 90 // Make sure that any stubs that the DFG is going to use are initialized. We want to -
trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp
r243744 r244811 185 185 186 186 if (logCompilationChanges(m_mode) || Options::logPhaseTimes()) 187 dataLog("DFG(Plan) compiling ", *m_codeBlock, " with ", m_mode, ", number of instructions = ", m_codeBlock->instructionCount(), "\n");187 dataLog("DFG(Plan) compiling ", *m_codeBlock, " with ", m_mode, ", instructions size = ", m_codeBlock->instructionsSize(), "\n"); 188 188 189 189 CompilationPath path = compileInThreadImpl(); -
trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp
r243232 r244811 70 70 return false; 71 71 72 if (!Options::bytecodeRangeToFTLCompile().isInRange(m_graph.m_profiledBlock->instruction Count()))72 if (!Options::bytecodeRangeToFTLCompile().isInRange(m_graph.m_profiledBlock->instructionsSize())) 73 73 return false; 74 74 -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r244324 r244811 402 402 CapabilityLevel canCompile(Graph& graph) 403 403 { 404 if (graph.m_codeBlock-> instructionCount() > Options::maximumFTLCandidateInstructionCount()) {404 if (graph.m_codeBlock->bytecodeCost() > Options::maximumFTLCandidateBytecodeCost()) { 405 405 if (verboseCapabilities()) 406 406 dataLog("FTL rejecting ", *graph.m_codeBlock, " because it's too big.\n"); -
trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp
r244764 r244811 169 169 PrintStream& out = WTF::dataFile(); 170 170 171 out.print("Generated ", state.graph.m_plan.mode(), " code for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITType::FTLJIT), ", instruction count = ", state.graph.m_codeBlock->instructionCount(), ":\n");171 out.print("Generated ", state.graph.m_plan.mode(), " code for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITType::FTLJIT), ", instructions size = ", state.graph.m_codeBlock->instructionsSize(), ":\n"); 172 172 173 173 LinkBuffer& linkBuffer = *state.finalizer->b3CodeLinkBuffer; -
trunk/Source/JavaScriptCore/ftl/FTLLink.cpp
r244764 r244811 72 72 compilation->addDescription( 73 73 Profiler::OriginStack(), 74 toCString("Generated FTL JIT code for ", CodeBlockWithJITType(codeBlock, JITType::FTLJIT), ", instruction count = ", graph.m_codeBlock->instructionCount(), ":\n"));74 toCString("Generated FTL JIT code for ", CodeBlockWithJITType(codeBlock, JITType::FTLJIT), ", instructions size = ", graph.m_codeBlock->instructionsSize(), ":\n")); 75 75 76 76 graph.ensureSSADominators(); -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r244764 r244811 908 908 m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->add( 909 909 static_cast<double>(result.size()) / 910 static_cast<double>(m_codeBlock->instruction Count()));910 static_cast<double>(m_codeBlock->instructionsSize())); 911 911 912 912 m_codeBlock->shrinkToFit(CodeBlock::LateShrink); -
trunk/Source/JavaScriptCore/jit/JITDisassembler.cpp
r244764 r244811 90 90 void JITDisassembler::dumpHeader(PrintStream& out, LinkBuffer& linkBuffer) 91 91 { 92 out.print("Generated Baseline JIT code for ", CodeBlockWithJITType(m_codeBlock, JITType::BaselineJIT), ", instruction count = ", m_codeBlock->instructionCount(), "\n");92 out.print("Generated Baseline JIT code for ", CodeBlockWithJITType(m_codeBlock, JITType::BaselineJIT), ", instructions size = ", m_codeBlock->instructionsSize(), "\n"); 93 93 out.print(" Source: ", m_codeBlock->sourceCodeOnOneLine(), "\n"); 94 94 out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.size()), "):\n"); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r244764 r244811 358 358 inline bool shouldJIT(CodeBlock* codeBlock) 359 359 { 360 if (!Options::bytecodeRangeToJITCompile().isInRange(codeBlock->instruction Count())360 if (!Options::bytecodeRangeToJITCompile().isInRange(codeBlock->instructionsSize()) 361 361 || !ensureGlobalJITWhitelist().contains(codeBlock)) 362 362 return false; -
trunk/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
r221822 r244811 41 41 , m_sourceCode(codeBlock->sourceCodeForTools()) 42 42 , m_hash(codeBlock->hash()) 43 , m_instructionCount(codeBlock->instruction Count())43 , m_instructionCount(codeBlock->instructionsSize()) 44 44 { 45 45 } -
trunk/Source/JavaScriptCore/runtime/Options.h
r244470 r244811 301 301 v(bool, breakOnThrow, false, Normal, nullptr) \ 302 302 \ 303 v(unsigned, maximumOptimizationCandidate InstructionCount, 100000, Normal, nullptr) \304 \ 305 v(unsigned, maximumFunctionForCallInlineCandidate InstructionCount, 120, Normal, nullptr) \306 v(unsigned, maximumFunctionForClosureCallInlineCandidate InstructionCount, 100, Normal, nullptr) \307 v(unsigned, maximumFunctionForConstructInlineCandidate InstructionCount, 100, Normal, nullptr) \308 \ 309 v(unsigned, maximumFTLCandidate InstructionCount, 20000, Normal, nullptr) \303 v(unsigned, maximumOptimizationCandidateBytecodeCost, 100000, Normal, nullptr) \ 304 \ 305 v(unsigned, maximumFunctionForCallInlineCandidateBytecodeCost, 120, Normal, nullptr) \ 306 v(unsigned, maximumFunctionForClosureCallInlineCandidateBytecodeCost, 100, Normal, nullptr) \ 307 v(unsigned, maximumFunctionForConstructInlineCandidateBytecoodeCost, 100, Normal, nullptr) \ 308 \ 309 v(unsigned, maximumFTLCandidateBytecodeCost, 20000, Normal, nullptr) \ 310 310 \ 311 311 /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \ … … 315 315 /* Maximum size of a caller for enabling inlining. This is purely to protect us */\ 316 316 /* from super long compiles that take a lot of memory. */\ 317 v(unsigned, maximumInliningCaller Size, 10000, Normal, nullptr) \317 v(unsigned, maximumInliningCallerBytecodeCost, 10000, Normal, nullptr) \ 318 318 \ 319 319 v(unsigned, maximumVarargsForInlining, 100, Normal, nullptr) \ … … 559 559 v(enableWebAssembly, useWebAssembly, SameOption) \ 560 560 v(verboseDFGByteCodeParsing, verboseDFGBytecodeParsing, SameOption) \ 561 v(maximumOptimizationCandidateInstructionCount, maximumOptimizationCandidateBytecodeCost, SameOption) \ 562 v(maximumFunctionForCallInlineCandidateInstructionCount, maximumFunctionForCallInlineCandidateBytecodeCost, SameOption) \ 563 v(maximumFunctionForClosureCallInlineCandidateInstructionCount, maximumFunctionForClosureCallInlineCandidateBytecodeCost, SameOption) \ 564 v(maximumFunctionForConstructInlineCandidateInstructionCount, maximumFunctionForConstructInlineCandidateBytecoodeCost, SameOption) \ 565 v(maximumFTLCandidateInstructionCount, maximumFTLCandidateBytecodeCost, SameOption) \ 566 v(maximumInliningCallerSize, maximumInliningCallerBytecodeCost, SameOption) \ 561 567 562 568 -
trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
r244764 r244811 435 435 #if USE(JSVALUE64) 436 436 unsigned bytecodeIndex = llintPC; 437 if (bytecodeIndex < codeBlock->instruction Count()) {437 if (bytecodeIndex < codeBlock->instructionsSize()) { 438 438 isValid = true; 439 439 return bytecodeIndex; … … 466 466 467 467 auto populateCodeLocation = [] (CodeBlock* codeBlock, unsigned bytecodeIndex, StackFrame::CodeLocation& location) { 468 if (bytecodeIndex < codeBlock->instruction Count()) {468 if (bytecodeIndex < codeBlock->instructionsSize()) { 469 469 int divot; 470 470 int startOffset;
Note:
See TracChangeset
for help on using the changeset viewer.