Changeset 128790 in webkit
- Timestamp:
- Sep 17, 2012 12:07:32 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r128777 r128790 1 2012-09-17 Filip Pizlo <fpizlo@apple.com> 2 3 Array profiling has convergence issues 4 https://bugs.webkit.org/show_bug.cgi?id=96891 5 6 Reviewed by Gavin Barraclough. 7 8 Now each array profiling site merges in the indexing type it observed into 9 the m_observedArrayModes bitset. The ArrayProfile also uses this to detect 10 cases where the structure must have gone polymorphic (if the bitset is 11 polymorphic then the structure must be). This achieves something like the 12 best of both worlds: on the one hand, we get a probabilistic structure that 13 we can use to optimize the monomorphic structure case, but on the other hand, 14 we get an accurate view of the set of types that were encountered. 15 16 * assembler/MacroAssemblerARMv7.h: 17 (JSC::MacroAssemblerARMv7::or32): 18 (MacroAssemblerARMv7): 19 * assembler/MacroAssemblerX86.h: 20 (JSC::MacroAssemblerX86::or32): 21 (MacroAssemblerX86): 22 * assembler/MacroAssemblerX86_64.h: 23 (JSC::MacroAssemblerX86_64::or32): 24 (MacroAssemblerX86_64): 25 * assembler/X86Assembler.h: 26 (X86Assembler): 27 (JSC::X86Assembler::orl_rm): 28 * bytecode/ArrayProfile.cpp: 29 (JSC::ArrayProfile::computeUpdatedPrediction): 30 * bytecode/ArrayProfile.h: 31 (JSC::ArrayProfile::addressOfArrayModes): 32 (JSC::ArrayProfile::structureIsPolymorphic): 33 * jit/JIT.h: 34 (JIT): 35 * jit/JITInlineMethods.h: 36 (JSC): 37 (JSC::JIT::emitArrayProfilingSite): 38 * jit/JITPropertyAccess.cpp: 39 (JSC::JIT::emit_op_get_by_val): 40 (JSC::JIT::emit_op_put_by_val): 41 (JSC::JIT::privateCompilePatchGetArrayLength): 42 * jit/JITPropertyAccess32_64.cpp: 43 (JSC::JIT::emit_op_get_by_val): 44 (JSC::JIT::emit_op_put_by_val): 45 (JSC::JIT::privateCompilePatchGetArrayLength): 46 * llint/LowLevelInterpreter.asm: 47 * llint/LowLevelInterpreter32_64.asm: 48 * llint/LowLevelInterpreter64.asm: 49 1 50 2012-09-17 Mark Lam <mark.lam@apple.com> 2 51 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r126214 r128790 314 314 m_assembler.orr(dest, dest, src); 315 315 } 316 317 void or32(RegisterID src, AbsoluteAddress dest) 318 { 319 move(TrustedImmPtr(dest.m_ptr), addressTempRegister); 320 load32(addressTempRegister, dataTempRegister); 321 or32(src, dataTempRegister); 322 store32(dataTempRegister, addressTempRegister); 323 } 316 324 317 325 void or32(TrustedImm32 imm, RegisterID dest) -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
r126214 r128790 85 85 } 86 86 87 void or32(RegisterID reg, AbsoluteAddress address) 88 { 89 m_assembler.orl_rm(reg, address.m_ptr); 90 } 91 87 92 void sub32(TrustedImm32 imm, AbsoluteAddress address) 88 93 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r126214 r128790 76 76 } 77 77 78 void or32(RegisterID reg, AbsoluteAddress address) 79 { 80 move(TrustedImmPtr(address.m_ptr), scratchRegister); 81 or32(reg, Address(scratchRegister)); 82 } 83 78 84 void sub32(TrustedImm32 imm, AbsoluteAddress address) 79 85 { -
trunk/Source/JavaScriptCore/assembler/X86Assembler.h
r123417 r128790 542 542 } 543 543 } 544 545 void orl_rm(RegisterID src, const void* addr) 546 { 547 m_formatter.oneByteOp(OP_OR_EvGv, src, addr); 548 } 544 549 #endif 545 550 -
trunk/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
r125637 r128790 44 44 } 45 45 46 if (hasTwoOrMoreBitsSet(m_observedArrayModes)) { 47 m_structureIsPolymorphic = true; 48 m_expectedStructure = 0; 49 } 50 46 51 if (operation == Collection 47 52 && m_expectedStructure -
trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h
r128400 r128790 71 71 72 72 Structure** addressOfLastSeenStructure() { return &m_lastSeenStructure; } 73 ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; } 73 74 74 75 void observeStructure(Structure* structure) … … 80 81 81 82 Structure* expectedStructure() const { return m_expectedStructure; } 82 bool structureIsPolymorphic() const { return m_structureIsPolymorphic; } 83 bool structureIsPolymorphic() const 84 { 85 return m_structureIsPolymorphic; 86 } 83 87 bool hasDefiniteStructure() const 84 88 { -
trunk/Source/JavaScriptCore/jit/JIT.h
r128400 r128790 450 450 void emitValueProfilingSite() { } 451 451 #endif 452 void emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile*); 453 void emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex); 452 454 453 455 enum FinalObjectMode { MayBeFinal, KnownNotFinal }; -
trunk/Source/JavaScriptCore/jit/JITInlineMethods.h
r128400 r128790 530 530 emitValueProfilingSite(m_bytecodeOffset); 531 531 } 532 #endif 532 #endif // ENABLE(VALUE_PROFILER) 533 534 inline void JIT::emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile* arrayProfile) 535 { 536 RegisterID structure = structureAndIndexingType; 537 RegisterID indexingType = structureAndIndexingType; 538 539 if (canBeOptimized()) { 540 storePtr(structure, arrayProfile->addressOfLastSeenStructure()); 541 load8(Address(structure, Structure::indexingTypeOffset()), indexingType); 542 move(TrustedImm32(1), scratch); 543 lshift32(indexingType, scratch); 544 or32(scratch, AbsoluteAddress(arrayProfile->addressOfArrayModes())); 545 } else 546 load8(Address(structure, Structure::indexingTypeOffset()), indexingType); 547 } 548 549 inline void JIT::emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex) 550 { 551 #if ENABLE(VALUE_PROFILER) 552 emitArrayProfilingSite(structureAndIndexingType, scratch, m_codeBlock->getOrAddArrayProfile(bytecodeIndex)); 553 #else 554 emitArrayProfilingSite(structureAndIndexingType, scratch, 0); 555 #endif 556 } 533 557 534 558 #if USE(JSVALUE32_64) -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r128425 r128790 112 112 emitJumpSlowCaseIfNotJSCell(regT0, base); 113 113 loadPtr(Address(regT0, JSCell::structureOffset()), regT2); 114 #if ENABLE(VALUE_PROFILER) 115 storePtr(regT2, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure()); 116 #endif 117 addSlowCase(branchTest8(Zero, Address(regT2, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage))); 114 emitArrayProfilingSite(regT2, regT3, currentInstruction[4].u.arrayProfile); 115 addSlowCase(branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage))); 118 116 119 117 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); … … 237 235 emitJumpSlowCaseIfNotJSCell(regT0, base); 238 236 loadPtr(Address(regT0, JSCell::structureOffset()), regT2); 239 #if ENABLE(VALUE_PROFILER) 240 storePtr(regT2, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure()); 241 #endif 242 addSlowCase(branchTest8(Zero, Address(regT2, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage))); 237 emitArrayProfilingSite(regT2, regT3, currentInstruction[4].u.arrayProfile); 238 addSlowCase(branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage))); 243 239 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); 244 240 addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset()))); … … 657 653 658 654 // Check eax is an array 659 loadPtr(Address(regT0, JSCell::structureOffset()), regT3); 660 #if ENABLE(VALUE_PROFILER) 661 storePtr(regT3, m_codeBlock->getOrAddArrayProfile(stubInfo->bytecodeIndex)->addressOfLastSeenStructure()); 662 #endif 663 load8(Address(regT3, Structure::indexingTypeOffset()), regT3); 664 Jump failureCases1 = branchTest32(Zero, regT3, TrustedImm32(IsArray)); 665 Jump failureCases2 = branchTest32(Zero, regT3, TrustedImm32(HasArrayStorage)); 655 loadPtr(Address(regT0, JSCell::structureOffset()), regT2); 656 emitArrayProfilingSiteForBytecodeIndex(regT2, regT1, stubInfo->bytecodeIndex); 657 Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray)); 658 Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage)); 666 659 667 660 // Checks out okay! - get the length from the storage -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r128425 r128790 211 211 emitJumpSlowCaseIfNotJSCell(base, regT1); 212 212 loadPtr(Address(regT0, JSCell::structureOffset()), regT1); 213 #if ENABLE(VALUE_PROFILER) 214 storePtr(regT1, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure()); 215 #endif 216 addSlowCase(branchTest8(Zero, Address(regT1, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage))); 213 emitArrayProfilingSite(regT1, regT3, currentInstruction[4].u.arrayProfile); 214 addSlowCase(branchTest32(Zero, regT1, TrustedImm32(HasArrayStorage))); 217 215 218 216 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); … … 270 268 emitJumpSlowCaseIfNotJSCell(base, regT1); 271 269 loadPtr(Address(regT0, JSCell::structureOffset()), regT1); 272 #if ENABLE(VALUE_PROFILER) 273 storePtr(regT1, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure()); 274 #endif 275 addSlowCase(branchTest8(Zero, Address(regT1, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage))); 270 emitArrayProfilingSite(regT1, regT3, currentInstruction[4].u.arrayProfile); 271 addSlowCase(branchTest32(Zero, regT1, TrustedImm32(HasArrayStorage))); 276 272 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); 277 273 addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset()))); … … 618 614 // Check for array 619 615 loadPtr(Address(regT0, JSCell::structureOffset()), regT2); 620 #if ENABLE(VALUE_PROFILER) 621 storePtr(regT2, m_codeBlock->getOrAddArrayProfile(stubInfo->bytecodeIndex)->addressOfLastSeenStructure()); 622 #endif 623 load8(Address(regT2, Structure::indexingTypeOffset()), regT3); 616 emitArrayProfilingSiteForBytecodeIndex(regT2, regT3, stubInfo->bytecodeIndex); 624 617 Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray)); 625 618 Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage)); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r128400 r128790 186 186 end 187 187 end) 188 end 189 190 macro arrayProfile(structureAndIndexingType, profile, scratch) 191 const structure = structureAndIndexingType 192 const indexingType = structureAndIndexingType 193 if VALUE_PROFILER 194 storep structure, ArrayProfile::m_lastSeenStructure[profile] 195 loadb Structure::m_indexingType[structure], indexingType 196 move 1, scratch 197 lshifti indexingType, scratch 198 ori scratch, ArrayProfile::m_observedArrayModes[profile] 199 else 200 loadb Structure::m_indexingType[structure], indexingType 201 end 188 202 end 189 203 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r128534 r128790 1177 1177 loadConstantOrVariablePayload(t0, CellTag, t3, .opGetArrayLengthSlow) 1178 1178 loadp JSCell::m_structure[t3], t2 1179 if VALUE_PROFILER 1180 storep t2, ArrayProfile::m_lastSeenStructure[t1] 1181 end 1182 loadb Structure::m_indexingType[t2], t1 1183 btiz t1, IsArray, .opGetArrayLengthSlow 1184 btiz t1, HasArrayStorage, .opGetArrayLengthSlow 1179 arrayProfile(t2, t1, t0) 1180 btiz t2, IsArray, .opGetArrayLengthSlow 1181 btiz t2, HasArrayStorage, .opGetArrayLengthSlow 1185 1182 loadi 4[PC], t1 1186 1183 loadp 32[PC], t2 … … 1309 1306 traceExecution() 1310 1307 loadi 8[PC], t2 1308 loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow) 1309 loadp JSCell::m_structure[t0], t2 1310 loadp 16[PC], t3 1311 arrayProfile(t2, t3, t1) 1312 btiz t2, HasArrayStorage, .opGetByValSlow 1311 1313 loadi 12[PC], t3 1312 loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)1313 1314 loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow) 1314 loadp JSCell::m_structure[t0], t31315 loadp 16[PC], t21316 if VALUE_PROFILER1317 storep t3, ArrayProfile::m_lastSeenStructure[t2]1318 end1319 btpz Structure::m_indexingType[t3], HasArrayStorage, .opGetByValSlow1320 1315 loadp JSObject::m_butterfly[t0], t3 1321 1316 biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opGetByValSlow … … 1393 1388 loadi 4[PC], t0 1394 1389 loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow) 1390 loadp JSCell::m_structure[t1], t2 1391 loadp 16[PC], t0 1392 arrayProfile(t2, t0, t3) 1393 btiz t2, HasArrayStorage, .opPutByValSlow 1395 1394 loadi 8[PC], t0 1396 1395 loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow) 1397 loadp JSCell::m_structure[t1], t31398 loadp 16[PC], t01399 if VALUE_PROFILER1400 storep t3, ArrayProfile::m_lastSeenStructure[t0]1401 end1402 btpz Structure::m_indexingType[t3], HasArrayStorage, .opPutByValSlow1403 1396 loadp JSObject::m_butterfly[t1], t0 1404 1397 biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r128534 r128790 1024 1024 loadConstantOrVariableCell(t0, t3, .opGetArrayLengthSlow) 1025 1025 loadp JSCell::m_structure[t3], t2 1026 if VALUE_PROFILER 1027 storep t2, ArrayProfile::m_lastSeenStructure[t1] 1028 end 1029 loadb Structure::m_indexingType[t2], t1 1030 btiz t1, IsArray, .opGetArrayLengthSlow 1031 btiz t1, HasArrayStorage, .opGetArrayLengthSlow 1026 arrayProfile(t2, t1, t0) 1027 btiz t2, IsArray, .opGetArrayLengthSlow 1028 btiz t2, HasArrayStorage, .opGetArrayLengthSlow 1032 1029 loadis 8[PB, PC, 8], t1 1033 1030 loadp 64[PB, PC, 8], t2 … … 1153 1150 traceExecution() 1154 1151 loadis 16[PB, PC, 8], t2 1152 loadConstantOrVariableCell(t2, t0, .opGetByValSlow) 1153 loadp JSCell::m_structure[t0], t2 1154 loadp 32[PB, PC, 8], t3 1155 arrayProfile(t2, t3, t1) 1155 1156 loadis 24[PB, PC, 8], t3 1156 loadConstantOrVariableCell(t2, t0, .opGetByValSlow)1157 btiz t2, HasArrayStorage, .opGetByValSlow 1157 1158 loadConstantOrVariableInt32(t3, t1, .opGetByValSlow) 1158 1159 sxi2p t1, t1 1159 loadp JSCell::m_structure[t0], t31160 loadp 32[PB, PC, 8], t21161 if VALUE_PROFILER1162 storep t3, ArrayProfile::m_lastSeenStructure[t2]1163 end1164 btbz Structure::m_indexingType[t3], HasArrayStorage, .opGetByValSlow1165 1160 loadp JSObject::m_butterfly[t0], t3 1166 1161 biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow … … 1236 1231 loadis 8[PB, PC, 8], t0 1237 1232 loadConstantOrVariableCell(t0, t1, .opPutByValSlow) 1233 loadp JSCell::m_structure[t1], t2 1234 loadp 32[PB, PC, 8], t0 1235 arrayProfile(t2, t0, t3) 1236 btiz t2, HasArrayStorage, .opPutByValSlow 1238 1237 loadis 16[PB, PC, 8], t0 1239 1238 loadConstantOrVariableInt32(t0, t2, .opPutByValSlow) 1240 1239 sxi2p t2, t2 1241 loadp JSCell::m_structure[t1], t31242 loadp 32[PB, PC, 8], t01243 if VALUE_PROFILER1244 storep t3, ArrayProfile::m_lastSeenStructure[t0]1245 end1246 btbz Structure::m_indexingType[t3], HasArrayStorage, .opPutByValSlow1247 1240 loadp JSObject::m_butterfly[t1], t0 1248 1241 biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow -
trunk/Source/WTF/ChangeLog
r128762 r128790 1 2012-09-17 Filip Pizlo <fpizlo@apple.com> 2 3 Array profiling has convergence issues 4 https://bugs.webkit.org/show_bug.cgi?id=96891 5 6 Reviewed by Gavin Barraclough. 7 8 Added functions for testing if something is a power of 2. 9 10 * wtf/MathExtras.h: 11 (hasZeroOrOneBitsSet): 12 (hasTwoOrMoreBitsSet): 13 1 14 2012-09-17 Ilya Tikhonovsky <loislo@chromium.org> 2 15 -
trunk/Source/WTF/wtf/MathExtras.h
r127114 r128790 295 295 } 296 296 297 template<typename T> inline bool hasZeroOrOneBitsSet(T value) 298 { 299 return !((value - 1) & value); 300 } 301 302 template<typename T> inline bool hasTwoOrMoreBitsSet(T value) 303 { 304 return !hasZeroOrOneBitsSet(value); 305 } 306 297 307 #if !COMPILER(MSVC) && !COMPILER(RVCT) && !OS(SOLARIS) 298 308 using std::isfinite;
Note: See TracChangeset
for help on using the changeset viewer.