Changeset 121215 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Jun 25, 2012, 7:14:07 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r121196 r121215 1 2012-06-22 Filip Pizlo <[email protected]> 2 3 Value profiling should use tier-up threshold randomization to get more coverage 4 https://bugs.webkit.org/show_bug.cgi?id=89802 5 6 Reviewed by Gavin Barraclough. 7 8 This patch causes both LLInt and Baseline JIT code to take the OSR slow path several 9 times before actually doing OSR. If we take the OSR slow path before the execution 10 count threshold is reached, then we just call CodeBlock::updateAllPredictions() to 11 compute the current latest least-upper-bound SpecType of all values seen in each 12 ValueProfile. 13 14 * bytecode/CodeBlock.cpp: 15 (JSC::CodeBlock::stronglyVisitStrongReferences): 16 (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): 17 (JSC): 18 (JSC::CodeBlock::updateAllPredictions): 19 (JSC::CodeBlock::shouldOptimizeNow): 20 * bytecode/CodeBlock.h: 21 (JSC::CodeBlock::llintExecuteCounter): 22 (JSC::CodeBlock::jitExecuteCounter): 23 (CodeBlock): 24 (JSC::CodeBlock::updateAllPredictions): 25 * bytecode/ExecutionCounter.cpp: 26 (JSC::ExecutionCounter::setThreshold): 27 (JSC::ExecutionCounter::status): 28 (JSC): 29 * bytecode/ExecutionCounter.h: 30 (JSC::ExecutionCounter::count): 31 (ExecutionCounter): 32 * dfg/DFGAbstractState.cpp: 33 (JSC::DFG::AbstractState::execute): 34 * dfg/DFGOperations.cpp: 35 * dfg/DFGSpeculativeJIT.cpp: 36 (JSC::DFG::SpeculativeJIT::compile): 37 * jit/JITStubs.cpp: 38 (JSC::DEFINE_STUB_FUNCTION): 39 * llint/LLIntSlowPaths.cpp: 40 (JSC::LLInt::jitCompileAndSetHeuristics): 41 (JSC::LLInt::entryOSR): 42 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 43 * runtime/JSGlobalObject.cpp: 44 (JSC::JSGlobalObject::JSGlobalObject): 45 (JSC): 46 * runtime/JSGlobalObject.h: 47 (JSGlobalObject): 48 (JSC::JSGlobalObject::weakRandomInteger): 49 * runtime/Options.cpp: 50 (Options): 51 (JSC::Options::initializeOptions): 52 * runtime/Options.h: 53 (Options): 54 * runtime/WeakRandom.h: 55 (WeakRandom): 56 (JSC::WeakRandom::seedUnsafe): 57 1 58 2012-06-25 Yong Li <[email protected]> 2 59 -
trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
r121098 r121215 10 10 ??0DynamicGlobalObjectScope@JSC@@QAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@@Z 11 11 ??0InternalFunction@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@@Z 12 ??0JSGlobalObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@PBUGlobalObjectMethodTable@1@@Z 12 13 ??0JSLock@JSC@@QAE@PAVExecState@1@@Z 13 14 ??0MD5@WTF@@QAE@XZ -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r121073 r121215 2105 2105 #endif 2106 2106 2107 #if ENABLE(DFG_JIT) 2108 if (hasCodeOrigins()) { 2109 // Make sure that executables that we have inlined don't die. 2110 // FIXME: If they would have otherwise died, we should probably trigger recompilation. 2111 for (size_t i = 0; i < inlineCallFrames().size(); ++i) { 2112 InlineCallFrame& inlineCallFrame = inlineCallFrames()[i]; 2113 visitor.append(&inlineCallFrame.executable); 2114 visitor.append(&inlineCallFrame.callee); 2115 } 2116 } 2117 2118 m_lazyOperandValueProfiles.computeUpdatedPredictions(Collection); 2119 #endif 2120 2121 #if ENABLE(VALUE_PROFILER) 2122 for (unsigned profileIndex = 0; profileIndex < numberOfArgumentValueProfiles(); ++profileIndex) 2123 valueProfileForArgument(profileIndex)->computeUpdatedPrediction(Collection); 2124 for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) 2125 valueProfile(profileIndex)->computeUpdatedPrediction(Collection); 2126 #endif 2107 updateAllPredictions(Collection); 2127 2108 } 2128 2109 … … 2575 2556 2576 2557 #if ENABLE(VALUE_PROFILER) 2577 bool CodeBlock::shouldOptimizeNow() 2578 { 2579 #if ENABLE(JIT_VERBOSE_OSR) 2580 dataLog("Considering optimizing %p...\n", this); 2581 #endif 2582 2583 #if ENABLE(VERBOSE_VALUE_PROFILE) 2584 dumpValueProfiles(); 2585 #endif 2586 2587 if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay) 2588 return true; 2589 2590 unsigned numberOfLiveNonArgumentValueProfiles = 0; 2591 unsigned numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full. 2558 void CodeBlock::updateAllPredictionsAndCountLiveness( 2559 OperationInProgress operation, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles) 2560 { 2561 numberOfLiveNonArgumentValueProfiles = 0; 2562 numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full. 2592 2563 for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { 2593 2564 ValueProfile* profile = getFromAllValueProfiles(i); … … 2597 2568 numberOfSamplesInProfiles += numSamples; 2598 2569 if (profile->m_bytecodeOffset < 0) { 2599 profile->computeUpdatedPrediction( );2570 profile->computeUpdatedPrediction(operation); 2600 2571 continue; 2601 2572 } 2602 2573 if (profile->numberOfSamples() || profile->m_prediction != SpecNone) 2603 2574 numberOfLiveNonArgumentValueProfiles++; 2604 profile->computeUpdatedPrediction(); 2605 } 2575 profile->computeUpdatedPrediction(operation); 2576 } 2577 2578 #if ENABLE(DFG_JIT) 2579 m_lazyOperandValueProfiles.computeUpdatedPredictions(operation); 2580 #endif 2581 } 2582 2583 void CodeBlock::updateAllPredictions(OperationInProgress operation) 2584 { 2585 unsigned ignoredValue1, ignoredValue2; 2586 updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2); 2587 } 2588 2589 bool CodeBlock::shouldOptimizeNow() 2590 { 2591 #if ENABLE(JIT_VERBOSE_OSR) 2592 dataLog("Considering optimizing %p...\n", this); 2593 #endif 2594 2595 #if ENABLE(VERBOSE_VALUE_PROFILE) 2596 dumpValueProfiles(); 2597 #endif 2598 2599 if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay) 2600 return true; 2601 2602 unsigned numberOfLiveNonArgumentValueProfiles; 2603 unsigned numberOfSamplesInProfiles; 2604 updateAllPredictionsAndCountLiveness(NoOperation, numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles); 2606 2605 2607 2606 #if ENABLE(JIT_VERBOSE_OSR) -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r121073 r121215 914 914 } 915 915 916 int32_tllintExecuteCounter() const917 { 918 return m_llintExecuteCounter .m_counter;916 const ExecutionCounter& llintExecuteCounter() const 917 { 918 return m_llintExecuteCounter; 919 919 } 920 920 … … 972 972 static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_totalCount); } 973 973 974 int32_t jitExecuteCounter() const { return m_jitExecuteCounter.m_counter; }974 const ExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; } 975 975 976 976 unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; } … … 1101 1101 #if ENABLE(VALUE_PROFILER) 1102 1102 bool shouldOptimizeNow(); 1103 void updateAllPredictions(OperationInProgress = NoOperation); 1103 1104 #else 1104 1105 bool shouldOptimizeNow() { return false; } 1106 void updateAllPredictions(OperationInProgress = NoOperation) { } 1105 1107 #endif 1106 1108 … … 1134 1136 #else 1135 1137 void tallyFrequentExitSites() { } 1138 #endif 1139 #if ENABLE(VALUE_PROFILER) 1140 void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles); 1136 1141 #endif 1137 1142 -
trunk/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
r110453 r121215 29 29 #include "CodeBlock.h" 30 30 #include "ExecutableAllocator.h" 31 #include <wtf/StringExtras.h> 31 32 32 33 namespace JSC { … … 126 127 127 128 // Compute the true total count. 128 double trueTotalCount = static_cast<double>(m_totalCount) + m_counter;129 double trueTotalCount = count(); 129 130 130 131 // Correct the threshold for current memory usage. … … 144 145 } 145 146 146 if (threshold > std::numeric_limits<int32_t>::max()) 147 threshold = std::numeric_limits<int32_t>::max(); 148 147 int32_t maxThreshold = 148 codeBlock->globalObject()->weakRandomInteger() % Options::maximumExecutionCountsBetweenCheckpoints; 149 if (threshold > maxThreshold) 150 threshold = maxThreshold; 151 149 152 m_counter = static_cast<int32_t>(-threshold); 150 153 … … 161 164 } 162 165 166 const char* ExecutionCounter::status() const 167 { 168 static char result[80]; 169 snprintf(result, sizeof(result), "%lf/%lf, %d", count(), static_cast<double>(m_activeThreshold), m_counter); 170 return result; 171 } 172 163 173 } // namespace JSC 164 174 -
trunk/Source/JavaScriptCore/bytecode/ExecutionCounter.h
r109802 r121215 39 39 void setNewThreshold(int32_t threshold, CodeBlock*); 40 40 void deferIndefinitely(); 41 double count() const { return static_cast<double>(m_totalCount) + m_counter; } 42 const char* status() const; 41 43 static double applyMemoryUsageHeuristics(int32_t value, CodeBlock*); 42 44 static int32_t applyMemoryUsageHeuristicsAndConvertToInt(int32_t value, CodeBlock*); -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r120767 r121215 1393 1393 // FIXME: Turn CheckStructure into StructureTransitionWatchpoint when possible! 1394 1394 AbstractValue& value = forNode(node.child1()); 1395 ASSERT( isCellSpeculation(value.m_type));1395 ASSERT(value.isClear() || isCellSpeculation(value.m_type)); // Value could be clear if we've proven must-exit due to a speculation statically known to be bad. 1396 1396 value.filter(node.structure()); 1397 1397 node.setCanExit(true); -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r121073 r121215 1239 1239 CodeBlock* codeBlock = debugInfo->codeBlock; 1240 1240 CodeBlock* alternative = codeBlock->alternative(); 1241 dataLog("Speculation failure in %p at @%u with executeCounter = % d, "1241 dataLog("Speculation failure in %p at @%u with executeCounter = %s, " 1242 1242 "reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, " 1243 1243 "success/fail %u/(%u+%u)\n", 1244 1244 codeBlock, 1245 1245 debugInfo->nodeIndex, 1246 alternative ? alternative->jitExecuteCounter() : 0,1246 alternative ? alternative->jitExecuteCounter().status() : 0, 1247 1247 alternative ? alternative->reoptimizationRetryCounter() : 0, 1248 1248 alternative ? alternative->optimizationDelayCounter() : 0, -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r120834 r121215 987 987 988 988 ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments()); 989 for (size_t i = 0; i < m_arguments.size(); ++i) { 990 NodeIndex nodeIndex = block.variablesAtHead.argument(i); 991 if (nodeIndex == NoNode || m_jit.codeBlock()->argumentIsCaptured(i)) 992 m_arguments[i] = ValueSource(ValueInRegisterFile); 993 else 994 m_arguments[i] = ValueSource::forSpeculation(at(nodeIndex).variableAccessData()->prediction()); 995 } 989 for (size_t i = 0; i < m_arguments.size(); ++i) 990 m_arguments[i] = ValueSource(ValueInRegisterFile); 996 991 997 992 m_state.reset(); -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r121073 r121215 1929 1929 1930 1930 #if ENABLE(JIT_VERBOSE_OSR) 1931 dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = % d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());1931 dataLog("%p: Entered optimize with bytecodeIndex = %u, executeCounter = %s, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, bytecodeIndex, codeBlock->jitExecuteCounter().status(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter()); 1932 1932 #endif 1933 1933 1934 if (!codeBlock->checkIfOptimizationThresholdReached()) 1934 if (!codeBlock->checkIfOptimizationThresholdReached()) { 1935 codeBlock->updateAllPredictions(); 1935 1936 return; 1937 } 1936 1938 1937 1939 if (codeBlock->hasOptimizedReplacement()) { -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r120499 r121215 265 265 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec) 266 266 { 267 codeBlock->updateAllPredictions(); 268 267 269 if (!codeBlock->checkIfJITThresholdReached()) { 268 270 #if ENABLE(JIT_VERBOSE_OSR) … … 301 303 { 302 304 #if ENABLE(JIT_VERBOSE_OSR) 303 dataLog("%p: Entered %s with executeCounter = %d\n", codeBlock, name, codeBlock->llintExecuteCounter()); 305 dataLog("%p: Entered %s with executeCounter = %s\n", codeBlock, name, 306 codeBlock->llintExecuteCounter().status()); 304 307 #endif 305 308 … … 347 350 348 351 #if ENABLE(JIT_VERBOSE_OSR) 349 dataLog("%p: Entered loop_osr with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter()); 352 dataLog("%p: Entered loop_osr with executeCounter = %s\n", codeBlock, 353 codeBlock->llintExecuteCounter().status()); 350 354 #endif 351 355 … … 377 381 378 382 #if ENABLE(JIT_VERBOSE_OSR) 379 dataLog("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter()); 383 dataLog("%p: Entered replace with executeCounter = %s\n", codeBlock, 384 codeBlock->llintExecuteCounter().status()); 380 385 #endif 381 386 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r121098 r121215 113 113 } 114 114 115 JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable) 116 : JSSegmentedVariableObject(globalData, structure, &m_symbolTable) 117 , m_globalScopeChain() 118 , m_weakRandom(Options::forceWeakRandomSeed ? Options::forcedWeakRandomSeed : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) 119 , m_evalEnabled(true) 120 , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable) 121 { 122 } 123 115 124 JSGlobalObject::~JSGlobalObject() 116 125 { -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r119779 r121215 176 176 177 177 protected: 178 explicit JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable = 0) 179 : JSSegmentedVariableObject(globalData, structure, &m_symbolTable) 180 , m_globalScopeChain() 181 , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) 182 , m_evalEnabled(true) 183 , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable) 184 { 185 } 178 JS_EXPORT_PRIVATE explicit JSGlobalObject(JSGlobalData&, Structure*, const GlobalObjectMethodTable* = 0); 186 179 187 180 void finishCreation(JSGlobalData& globalData) … … 329 322 330 323 double weakRandomNumber() { return m_weakRandom.get(); } 324 unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } 331 325 protected: 332 326 -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r120834 r121215 68 68 int32_t executionCounterIncrementForReturn; 69 69 70 int32_t maximumExecutionCountsBetweenCheckpoints; 71 70 72 unsigned desiredSpeculativeSuccessFailRatio; 71 73 … … 95 97 unsigned numberOfGCMarkers; 96 98 unsigned opaqueRootMergeThreshold; 99 100 bool forceWeakRandomSeed; 101 unsigned forcedWeakRandomSeed; 97 102 98 103 #if ENABLE(RUN_TIME_HEURISTICS) … … 185 190 SET(executionCounterIncrementForLoop, 1); 186 191 SET(executionCounterIncrementForReturn, 15); 192 193 SET(maximumExecutionCountsBetweenCheckpoints, 1000); 187 194 188 195 SET(desiredSpeculativeSuccessFailRatio, 6); … … 228 235 ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) > 0); 229 236 ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max())); 237 238 SET(forceWeakRandomSeed, false); 239 SET(forcedWeakRandomSeed, 0); 230 240 } 231 241 -
trunk/Source/JavaScriptCore/runtime/Options.h
r120834 r121215 54 54 extern int32_t executionCounterIncrementForReturn; 55 55 56 extern int32_t maximumExecutionCountsBetweenCheckpoints; 57 56 58 extern unsigned desiredSpeculativeSuccessFailRatio; 57 59 … … 82 84 JS_EXPORTDATA extern unsigned opaqueRootMergeThreshold; 83 85 86 extern bool forceWeakRandomSeed; 87 extern unsigned forcedWeakRandomSeed; 88 84 89 void initializeOptions(); 85 90 -
trunk/Source/JavaScriptCore/runtime/WeakRandom.h
r95901 r121215 63 63 { 64 64 } 65 66 // Returns the seed provided that you've never called get() or getUint32(). 67 unsigned seedUnsafe() const { return m_high; } 65 68 66 69 double get()
Note:
See TracChangeset
for help on using the changeset viewer.