Changeset 155023 in webkit for trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp
- Timestamp:
- Sep 3, 2013, 11:26:04 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp
r153216 r155023 29 29 #if ENABLE(DFG_JIT) 30 30 31 #include "CodeBlock.h" 32 31 33 namespace JSC { namespace DFG { 32 34 … … 60 62 } 61 63 64 void JITCode::reconstruct( 65 CodeBlock* codeBlock, CodeOrigin codeOrigin, unsigned streamIndex, 66 Operands<ValueRecovery>& result) 67 { 68 variableEventStream.reconstruct( 69 codeBlock, codeOrigin, minifiedDFG, streamIndex, result); 70 } 71 72 void JITCode::reconstruct( 73 ExecState* exec, CodeBlock* codeBlock, CodeOrigin codeOrigin, unsigned streamIndex, 74 Operands<JSValue>& result) 75 { 76 Operands<ValueRecovery> recoveries; 77 reconstruct(codeBlock, codeOrigin, streamIndex, recoveries); 78 79 result = Operands<JSValue>(OperandsLike, recoveries); 80 for (size_t i = result.size(); i--;) { 81 int operand = result.operandForIndex(i); 82 83 if (operandIsArgument(operand) 84 && !operandToArgument(operand) 85 && codeBlock->codeType() == FunctionCode 86 && codeBlock->specializationKind() == CodeForConstruct) { 87 // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will 88 // also never be used. It doesn't matter what we put into the value for this, 89 // but it has to be an actual value that can be grokked by subsequent DFG passes, 90 // so we sanitize it here by turning it into Undefined. 91 result[i] = jsUndefined(); 92 continue; 93 } 94 95 ValueRecovery recovery = recoveries[i]; 96 JSValue value; 97 switch (recovery.technique()) { 98 case AlreadyInJSStack: 99 case AlreadyInJSStackAsUnboxedCell: 100 case AlreadyInJSStackAsUnboxedBoolean: 101 value = exec->r(operand).jsValue(); 102 break; 103 case AlreadyInJSStackAsUnboxedInt32: 104 value = jsNumber(exec->r(operand).unboxedInt32()); 105 break; 106 case AlreadyInJSStackAsUnboxedDouble: 107 value = jsDoubleNumber(exec->r(operand).unboxedDouble()); 108 break; 109 case Constant: 110 value = recovery.constant(); 111 break; 112 default: 113 RELEASE_ASSERT_NOT_REACHED(); 114 break; 115 } 116 result[i] = value; 117 } 118 } 119 120 #if ENABLE(FTL_JIT) 121 bool JITCode::checkIfOptimizationThresholdReached(CodeBlock* codeBlock) 122 { 123 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 124 return tierUpCounter.checkIfThresholdCrossedAndSet(codeBlock->baselineVersion()); 125 } 126 127 void JITCode::optimizeNextInvocation(CodeBlock* codeBlock) 128 { 129 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 130 if (Options::verboseOSR()) 131 dataLog(*codeBlock, ": FTL-optimizing next invocation.\n"); 132 tierUpCounter.setNewThreshold(0, codeBlock->baselineVersion()); 133 } 134 135 void JITCode::dontOptimizeAnytimeSoon(CodeBlock* codeBlock) 136 { 137 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 138 if (Options::verboseOSR()) 139 dataLog(*codeBlock, ": Not FTL-optimizing anytime soon.\n"); 140 tierUpCounter.deferIndefinitely(); 141 } 142 143 void JITCode::optimizeAfterWarmUp(CodeBlock* codeBlock) 144 { 145 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 146 if (Options::verboseOSR()) 147 dataLog(*codeBlock, ": FTL-optimizing after warm-up.\n"); 148 CodeBlock* baseline = codeBlock->baselineVersion(); 149 tierUpCounter.setNewThreshold( 150 baseline->adjustedCounterValue(Options::thresholdForFTLOptimizeAfterWarmUp()), 151 baseline); 152 } 153 154 void JITCode::optimizeSoon(CodeBlock* codeBlock) 155 { 156 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 157 if (Options::verboseOSR()) 158 dataLog(*codeBlock, ": FTL-optimizing soon.\n"); 159 CodeBlock* baseline = codeBlock->baselineVersion(); 160 tierUpCounter.setNewThreshold( 161 baseline->adjustedCounterValue(Options::thresholdForFTLOptimizeSoon()), 162 baseline); 163 } 164 165 void JITCode::forceOptimizationSlowPathConcurrently(CodeBlock* codeBlock) 166 { 167 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 168 if (Options::verboseOSR()) 169 dataLog(*codeBlock, ": Forcing slow path concurrently for FTL entry.\n"); 170 tierUpCounter.forceSlowPathConcurrently(); 171 } 172 173 void JITCode::setOptimizationThresholdBasedOnCompilationResult( 174 CodeBlock* codeBlock, CompilationResult result) 175 { 176 ASSERT(codeBlock->jitType() == JITCode::DFGJIT); 177 switch (result) { 178 case CompilationSuccessful: 179 optimizeNextInvocation(codeBlock); 180 return; 181 case CompilationFailed: 182 dontOptimizeAnytimeSoon(codeBlock); 183 codeBlock->baselineVersion()->m_didFailFTLCompilation = true; 184 return; 185 case CompilationDeferred: 186 optimizeAfterWarmUp(codeBlock); 187 return; 188 case CompilationInvalidated: 189 // This is weird - it will only happen in cases when the DFG code block (i.e. 190 // the code block that this JITCode belongs to) is also invalidated. So it 191 // doesn't really matter what we do. But, we do the right thing anyway. Note 192 // that us counting the reoptimization actually means that we might count it 193 // twice. But that's generally OK. It's better to overcount reoptimizations 194 // than it is to undercount them. 195 codeBlock->baselineVersion()->countReoptimization(); 196 optimizeAfterWarmUp(codeBlock); 197 return; 198 } 199 RELEASE_ASSERT_NOT_REACHED(); 200 } 201 #endif // ENABLE(FTL_JIT) 202 62 203 } } // namespace JSC::DFG 63 204
Note:
See TracChangeset
for help on using the changeset viewer.