Changeset 156468 in webkit
- Timestamp:
- Sep 26, 2013 10:16:47 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r156467 r156468 1 2013-09-26 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 op_to_this shouldn't use value profiling 4 https://bugs.webkit.org/show_bug.cgi?id=121920 5 6 Reviewed by Geoffrey Garen. 7 8 Updated a couple tests that waited for two DFG compiles, but with this patch we 9 don't do two compiles any more, so we don't want to wait forever. 10 11 * js/script-tests/dfg-convert-this-polymorphic-object-then-exit-on-other.js: 12 * js/script-tests/dfg-convert-this-polymorphic-object-then-exit-on-string.js: 13 1 14 2013-09-26 Andreas Kling <akling@apple.com> 2 15 -
trunk/LayoutTests/js/script-tests/dfg-convert-this-polymorphic-object-then-exit-on-other.js
r155201 r156468 12 12 noInline(foo); 13 13 14 for (var i = 0; i < 1000; i = dfgIncrement({f:foo, i: dfgIncrement({f:foo, i:i + 1, n:100}), n:500, compiles:2})) {14 for (var i = 0; i < 1000; i = dfgIncrement({f:foo, i:i + 1, n:500})) { 15 15 var me; 16 16 if (i < 150) -
trunk/LayoutTests/js/script-tests/dfg-convert-this-polymorphic-object-then-exit-on-string.js
r155201 r156468 14 14 noInline(foo); 15 15 16 for (var i = 0; i < 1000; i = dfgIncrement({f:foo, i: dfgIncrement({f:foo, i:i + 1, n:100}), n:500, compiles:2})) {16 for (var i = 0; i < 1000; i = dfgIncrement({f:foo, i:i + 1, n:500})) { 17 17 var me; 18 18 if (i < 150) -
trunk/Source/JavaScriptCore/ChangeLog
r156464 r156468 1 2013-09-26 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 op_to_this shouldn't use value profiling 4 https://bugs.webkit.org/show_bug.cgi?id=121920 5 6 Reviewed by Geoffrey Garen. 7 8 Currently it's the only opcode that uses m_singletonValue, which is unnecessary. Our current plan is 9 to remove m_singletonValue so that GenGC can have a simpler story for handling CodeBlocks/FunctionExecutables 10 during nursery collections. 11 12 This patch adds an inline cache for the Structure of to_this so it no longer depends on the ValueProfile's 13 m_singletonValue. Since nobody uses m_singletonValue now, this patch also removes m_singletonValue from 14 ValueProfile. 15 16 * bytecode/CodeBlock.cpp: 17 (JSC::CodeBlock::CodeBlock): 18 (JSC::CodeBlock::finalizeUnconditionally): 19 (JSC::CodeBlock::stronglyVisitStrongReferences): 20 (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): 21 (JSC::CodeBlock::updateAllValueProfilePredictions): 22 (JSC::CodeBlock::updateAllPredictions): 23 (JSC::CodeBlock::shouldOptimizeNow): 24 * bytecode/CodeBlock.h: 25 (JSC::CodeBlock::updateAllValueProfilePredictions): 26 (JSC::CodeBlock::updateAllPredictions): 27 * bytecode/LazyOperandValueProfile.cpp: 28 (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions): 29 * bytecode/LazyOperandValueProfile.h: 30 * bytecode/ValueProfile.h: 31 (JSC::ValueProfileBase::ValueProfileBase): 32 (JSC::ValueProfileBase::briefDescription): 33 (JSC::ValueProfileBase::dump): 34 (JSC::ValueProfileBase::computeUpdatedPrediction): 35 * bytecompiler/BytecodeGenerator.cpp: 36 (JSC::BytecodeGenerator::BytecodeGenerator): 37 * dfg/DFGByteCodeParser.cpp: 38 (JSC::DFG::ByteCodeParser::parseBlock): 39 * jit/JITOpcodes.cpp: 40 (JSC::JIT::emit_op_to_this): 41 (JSC::JIT::emitSlow_op_to_this): 42 * jit/JITOpcodes32_64.cpp: 43 (JSC::JIT::emit_op_to_this): 44 (JSC::JIT::emitSlow_op_to_this): 45 * llint/LowLevelInterpreter32_64.asm: 46 * llint/LowLevelInterpreter64.asm: 47 * runtime/CommonSlowPaths.cpp: 48 (JSC::SLOW_PATH_DECL): 49 1 50 2013-09-25 Oliver Hunt <oliver@apple.com> 2 51 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r156376 r156468 1735 1735 // fallthrough 1736 1736 } 1737 case op_to_this:1738 1737 case op_get_by_id: 1739 1738 case op_call_varargs: { … … 2239 2238 case op_get_array_length: 2240 2239 break; 2240 case op_to_this: 2241 if (!curInstruction[2].u.structure || Heap::isMarked(curInstruction[2].u.structure.get())) 2242 break; 2243 if (Options::verboseOSR()) 2244 dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get()); 2245 curInstruction[2].u.structure.clear(); 2246 break; 2241 2247 case op_get_callee: 2242 2248 if (!curInstruction[2].u.jsCell || Heap::isMarked(curInstruction[2].u.jsCell.get())) … … 2419 2425 m_objectAllocationProfiles[i].visitAggregate(visitor); 2420 2426 2421 updateAllPredictions( Collection);2427 updateAllPredictions(); 2422 2428 } 2423 2429 … … 3094 3100 } 3095 3101 3096 void CodeBlock::updateAllPredictionsAndCountLiveness( 3097 HeapOperation operation, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles) 3102 void CodeBlock::updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles) 3098 3103 { 3099 3104 ConcurrentJITLocker locker(m_lock); … … 3108 3113 numberOfSamplesInProfiles += numSamples; 3109 3114 if (profile->m_bytecodeOffset < 0) { 3110 profile->computeUpdatedPrediction(locker , operation);3115 profile->computeUpdatedPrediction(locker); 3111 3116 continue; 3112 3117 } 3113 3118 if (profile->numberOfSamples() || profile->m_prediction != SpecNone) 3114 3119 numberOfLiveNonArgumentValueProfiles++; 3115 profile->computeUpdatedPrediction(locker , operation);3120 profile->computeUpdatedPrediction(locker); 3116 3121 } 3117 3122 3118 3123 #if ENABLE(DFG_JIT) 3119 m_lazyOperandValueProfiles.computeUpdatedPredictions(locker , operation);3120 #endif 3121 } 3122 3123 void CodeBlock::updateAllValueProfilePredictions( HeapOperation operation)3124 m_lazyOperandValueProfiles.computeUpdatedPredictions(locker); 3125 #endif 3126 } 3127 3128 void CodeBlock::updateAllValueProfilePredictions() 3124 3129 { 3125 3130 unsigned ignoredValue1, ignoredValue2; 3126 updateAllPredictionsAndCountLiveness( operation,ignoredValue1, ignoredValue2);3131 updateAllPredictionsAndCountLiveness(ignoredValue1, ignoredValue2); 3127 3132 } 3128 3133 … … 3139 3144 } 3140 3145 3141 void CodeBlock::updateAllPredictions( HeapOperation operation)3142 { 3143 updateAllValueProfilePredictions( operation);3146 void CodeBlock::updateAllPredictions() 3147 { 3148 updateAllValueProfilePredictions(); 3144 3149 updateAllArrayPredictions(); 3145 3150 } … … 3161 3166 unsigned numberOfLiveNonArgumentValueProfiles; 3162 3167 unsigned numberOfSamplesInProfiles; 3163 updateAllPredictionsAndCountLiveness( NoOperation,numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles);3168 updateAllPredictionsAndCountLiveness(numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles); 3164 3169 3165 3170 if (Options::verboseOSR()) { -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r156300 r156468 871 871 #if ENABLE(VALUE_PROFILER) 872 872 bool shouldOptimizeNow(); 873 void updateAllValueProfilePredictions( HeapOperation = NoOperation);873 void updateAllValueProfilePredictions(); 874 874 void updateAllArrayPredictions(); 875 void updateAllPredictions( HeapOperation = NoOperation);875 void updateAllPredictions(); 876 876 #else 877 877 bool updateAllPredictionsAndCheckIfShouldOptimizeNow() { return false; } 878 void updateAllValueProfilePredictions( HeapOperation = NoOperation) { }878 void updateAllValueProfilePredictions() { } 879 879 void updateAllArrayPredictions() { } 880 void updateAllPredictions( HeapOperation = NoOperation) { }880 void updateAllPredictions() { } 881 881 #endif 882 882 … … 942 942 943 943 #if ENABLE(VALUE_PROFILER) 944 void updateAllPredictionsAndCountLiveness( HeapOperation,unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);944 void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles); 945 945 #endif 946 946 -
trunk/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp
r156050 r156468 36 36 CompressedLazyOperandValueProfileHolder::~CompressedLazyOperandValueProfileHolder() { } 37 37 38 void CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions(const ConcurrentJITLocker& locker , HeapOperation operation)38 void CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions(const ConcurrentJITLocker& locker) 39 39 { 40 40 if (!m_data) … … 42 42 43 43 for (unsigned i = 0; i < m_data->size(); ++i) 44 m_data->at(i).computeUpdatedPrediction(locker , operation);44 m_data->at(i).computeUpdatedPrediction(locker); 45 45 } 46 46 -
trunk/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.h
r156050 r156468 158 158 ~CompressedLazyOperandValueProfileHolder(); 159 159 160 void computeUpdatedPredictions(const ConcurrentJITLocker& , HeapOperation);160 void computeUpdatedPredictions(const ConcurrentJITLocker&); 161 161 162 162 LazyOperandValueProfile* add( -
trunk/Source/JavaScriptCore/bytecode/ValueProfile.h
r156050 r156468 56 56 , m_prediction(SpecNone) 57 57 , m_numberOfSamplesInPrediction(0) 58 , m_singletonValueIsTop(false)59 58 { 60 59 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) … … 66 65 , m_prediction(SpecNone) 67 66 , m_numberOfSamplesInPrediction(0) 68 , m_singletonValueIsTop(false)69 67 { 70 68 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) … … 118 116 119 117 StringPrintStream out; 120 121 if (m_singletonValueIsTop) 122 out.print("predicting ", SpeculationDump(m_prediction)); 123 else if (m_singletonValue) 124 out.print("predicting ", m_singletonValue); 125 118 out.print("predicting ", SpeculationDump(m_prediction)); 126 119 return out.toCString(); 127 120 } … … 130 123 { 131 124 out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction)); 132 out.printf(", value = ");133 if (m_singletonValueIsTop)134 out.printf("TOP");135 else136 out.print(m_singletonValue);137 125 bool first = true; 138 126 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { … … 151 139 // Updates the prediction and returns the new one. Never call this from any thread 152 140 // that isn't executing the code. 153 SpeculatedType computeUpdatedPrediction(const ConcurrentJITLocker& , HeapOperation operation = NoOperation)141 SpeculatedType computeUpdatedPrediction(const ConcurrentJITLocker&) 154 142 { 155 143 for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { … … 161 149 mergeSpeculation(m_prediction, speculationFromValue(value)); 162 150 163 if (!m_singletonValueIsTop && !!value) {164 if (!m_singletonValue)165 m_singletonValue = value;166 else if (m_singletonValue != value)167 m_singletonValueIsTop = true;168 }169 170 151 m_buckets[i] = JSValue::encode(JSValue()); 171 152 } 172 153 173 if (operation == Collection174 && !m_singletonValueIsTop175 && !!m_singletonValue176 && m_singletonValue.isCell()177 && !Heap::isMarked(m_singletonValue.asCell()))178 m_singletonValueIsTop = true;179 180 154 return m_prediction; 181 155 } … … 186 160 unsigned m_numberOfSamplesInPrediction; 187 161 188 bool m_singletonValueIsTop;189 JSValue m_singletonValue;190 191 162 EncodedJSValue m_buckets[totalNumberOfBuckets]; 192 163 }; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r156464 r156468 388 388 emitCreateThis(&m_thisRegister); 389 389 } else if (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks) { 390 UnlinkedValueProfile profile = emitProfiledOpcode(op_to_this);390 emitOpcode(op_to_this); 391 391 instructions().append(kill(&m_thisRegister)); 392 instructions().append( profile);392 instructions().append(0); 393 393 } 394 394 for (size_t i = 0; i < deconstructedParameters.size(); i++) { -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r156376 r156468 1906 1906 Node* op1 = getThis(); 1907 1907 if (op1->op() != ToThis) { 1908 ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock); 1909 ValueProfile* profile = 1910 m_inlineStackTop->m_profiledBlock->valueProfileForBytecodeOffset(m_currentIndex); 1911 profile->computeUpdatedPrediction(locker); 1912 #if DFG_ENABLE(DEBUG_VERBOSE) 1913 dataLogF("[bc#%u]: profile %p: ", m_currentIndex, profile); 1914 profile->dump(WTF::dataFile()); 1915 dataLogF("\n"); 1916 #endif 1917 if (profile->m_singletonValueIsTop 1918 || !profile->m_singletonValue 1919 || !profile->m_singletonValue.isCell() 1920 || profile->m_singletonValue.asCell()->classInfo() != Structure::info() 1921 || static_cast<Structure*>(profile->m_singletonValue.asCell())->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis) 1908 Structure* cachedStructure = currentInstruction[2].u.structure.get(); 1909 if (!cachedStructure 1910 || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis 1911 || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex) 1912 || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) { 1922 1913 setThis(addToGraph(ToThis, op1)); 1923 else {1914 } else { 1924 1915 addToGraph( 1925 1916 CheckStructure, 1926 OpInfo(m_graph.addStructureSet( jsCast<Structure*>(profile->m_singletonValue.asCell()))),1917 OpInfo(m_graph.addStructureSet(cachedStructure)), 1927 1918 op1); 1928 1919 } -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r156376 r156468 866 866 void JIT::emit_op_to_this(Instruction* currentInstruction) 867 867 { 868 WriteBarrierBase<Structure>* cachedStructure = ¤tInstruction[2].u.structure; 868 869 emitGetVirtualRegister(currentInstruction[1].u.operand, regT1); 869 870 870 871 emitJumpSlowCaseIfNotJSCell(regT1); 871 872 loadPtr(Address(regT1, JSCell::structureOffset()), regT0); 872 if (shouldEmitProfiling())873 emitValueProfilingSite(regT4);874 873 875 874 addSlowCase(branch8(NotEqual, Address(regT0, Structure::typeInfoTypeOffset()), TrustedImm32(FinalObjectType))); 875 loadPtr(cachedStructure, regT2); 876 addSlowCase(branchPtr(NotEqual, regT0, regT2)); 876 877 } 877 878 … … 944 945 void JIT::emitSlow_op_to_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 945 946 { 947 linkSlowCase(iter); 946 948 linkSlowCase(iter); 947 949 linkSlowCase(iter); -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r156376 r156468 1181 1181 void JIT::emit_op_to_this(Instruction* currentInstruction) 1182 1182 { 1183 WriteBarrierBase<Structure>* cachedStructure = ¤tInstruction[2].u.structure; 1183 1184 int thisRegister = currentInstruction[1].u.operand; 1184 1185 … … 1187 1188 addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::CellTag))); 1188 1189 loadPtr(Address(regT2, JSCell::structureOffset()), regT0); 1189 if (shouldEmitProfiling()) {1190 move(regT3, regT1);1191 emitValueProfilingSite(regT4);1192 }1193 1190 addSlowCase(branch8(NotEqual, Address(regT0, Structure::typeInfoTypeOffset()), TrustedImm32(FinalObjectType))); 1191 loadPtr(cachedStructure, regT2); 1192 addSlowCase(branchPtr(NotEqual, regT0, regT2)); 1194 1193 } 1195 1194 … … 1197 1196 { 1198 1197 int dst = currentInstruction[1].u.operand; 1198 linkSlowCase(iter); 1199 1199 linkSlowCase(iter); 1200 1200 linkSlowCase(iter); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r156376 r156468 432 432 loadp JSCell::m_structure[t0], t0 433 433 bbneq Structure::m_typeInfo + TypeInfo::m_type[t0], FinalObjectType, .opToThisSlow 434 valueProfile(CellTag, t0, 8, t1) 434 loadpFromInstruction(2, t2) 435 bpneq t0, t2, .opToThisSlow 435 436 dispatch(3) 436 437 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r156376 r156468 312 312 loadp JSCell::m_structure[t0], t0 313 313 bbneq Structure::m_typeInfo + TypeInfo::m_type[t0], FinalObjectType, .opToThisSlow 314 valueProfile(t0, 2, t1) 314 loadpFromInstruction(2, t2) 315 bpneq t0, t2, .opToThisSlow 315 316 dispatch(3) 316 317 -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r156376 r156468 231 231 BEGIN(); 232 232 JSValue v1 = OP(1).jsValue(); 233 #if ENABLE(VALUE_PROFILER)234 pc[OPCODE_LENGTH(op_to_this) - 1].u.profile->m_buckets[0] =235 JSValue::encode(v1.structureOrUndefined());236 #endif 233 if (v1.isCell()) 234 pc[2].u.structure.set(exec->vm(), exec->codeBlock()->ownerExecutable(), v1.asCell()->structure()); 235 else 236 pc[2].u.structure.clear(); 237 237 RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode)); 238 238 }
Note: See TracChangeset
for help on using the changeset viewer.