Changeset 59056 in webkit for trunk/JavaScriptCore
- Timestamp:
- May 9, 2010, 4:42:22 AM (15 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r59055 r59056 1 2010-05-09 Oliver Hunt <[email protected]> 2 3 Reviewed by Maciej Stachowiak. 4 5 Improve string indexing performance 6 https://bugs.webkit.org/show_bug.cgi?id=38814 7 8 Add an assembly stub to do indexed loads from strings much 9 more cheaply than the current stub dispatch logic. We can 10 do this because we are able to make guarantees about the 11 register contents when entering the stub so the call overhead 12 is negligible. 13 14 * jit/JIT.h: 15 * jit/JITInlineMethods.h: 16 * jit/JITOpcodes.cpp: 17 * jit/JITPropertyAccess.cpp: 18 (JSC::JIT::stringGetByValStubGenerator): 19 (JSC::JIT::emitSlow_op_get_by_val): 20 Moved from JITOpcodes.cpp to keep the slowcase next to 21 the normal case codegen as we do for everything else. 22 * jit/JITPropertyAccess32_64.cpp: 23 (JSC::JIT::stringGetByValStubGenerator): 24 (JSC::JIT::emitSlow_op_get_by_val): 25 * jit/JSInterfaceJIT.h: 26 (JSC::JSInterfaceJIT::emitFastArithImmToInt): 27 1 28 2010-05-09 Maciej Stachowiak <[email protected]> 2 29 -
trunk/JavaScriptCore/jit/JIT.h
r58986 r59056 448 448 #endif 449 449 void emitFastArithReTagImmediate(RegisterID src, RegisterID dest); 450 void emitFastArithImmToInt(RegisterID);451 450 void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest); 452 451 … … 905 904 #endif 906 905 #endif 906 static PassRefPtr<NativeExecutable> stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool); 907 907 } JIT_CLASS_ALIGNMENT; 908 908 -
trunk/JavaScriptCore/jit/JITInlineMethods.h
r58902 r59056 821 821 } 822 822 823 ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg)824 {825 #if USE(JSVALUE64)826 UNUSED_PARAM(reg);827 #else828 rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg);829 #endif830 }831 832 823 // operand is int32_t, must have been zero-extended if register is 64-bit. 833 824 ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest) -
trunk/JavaScriptCore/jit/JITOpcodes.cpp
r59040 r59056 1408 1408 } 1409 1409 1410 void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)1411 {1412 unsigned dst = currentInstruction[1].u.operand;1413 unsigned base = currentInstruction[2].u.operand;1414 unsigned property = currentInstruction[3].u.operand;1415 1416 linkSlowCase(iter); // property int32 check1417 linkSlowCaseIfNotJSCell(iter, base); // base cell check1418 linkSlowCase(iter); // base array check1419 linkSlowCase(iter); // vector length check1420 linkSlowCase(iter); // empty value1421 1422 JITStubCall stubCall(this, cti_op_get_by_val);1423 stubCall.addArgument(base, regT2);1424 stubCall.addArgument(property, regT2);1425 stubCall.call(dst);1426 }1427 1428 1410 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1429 1411 { -
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r55564 r59056 53 53 namespace JSC { 54 54 55 PassRefPtr<NativeExecutable> JIT::stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool) 56 { 57 JSInterfaceJIT jit; 58 JumpList failures; 59 failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr))); 60 failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount)))); 61 #if USE(JSVALUE64) 62 jit.zeroExtend32ToPtr(regT1, regT1); 63 #else 64 jit.emitFastArithImmToInt(regT1); 65 #endif 66 67 // Load string length to regT1, and start the process of loading the data pointer into regT0 68 jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2); 69 jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0); 70 jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0); 71 72 // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large 73 failures.append(jit.branch32(AboveOrEqual, regT1, regT2)); 74 75 // Load the character 76 jit.load16(BaseIndex(regT0, regT1, TimesTwo, 0), regT0); 77 78 failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100))); 79 jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1); 80 jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0); 81 jit.ret(); 82 83 failures.link(&jit); 84 jit.move(Imm32(0), regT0); 85 jit.ret(); 86 87 LinkBuffer patchBuffer(&jit, pool); 88 return adoptRef(new NativeExecutable(patchBuffer.finalizeCode())); 89 } 90 55 91 void JIT::emit_op_get_by_val(Instruction* currentInstruction) 56 92 { … … 82 118 83 119 emitPutVirtualRegister(dst); 120 } 121 122 void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 123 { 124 unsigned dst = currentInstruction[1].u.operand; 125 unsigned base = currentInstruction[2].u.operand; 126 unsigned property = currentInstruction[3].u.operand; 127 128 linkSlowCase(iter); // property int32 check 129 linkSlowCaseIfNotJSCell(iter, base); // base cell check 130 Jump nonCell = jump(); 131 linkSlowCase(iter); // base array check 132 Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)); 133 emitNakedCall(m_globalData->getThunk(stringGetByValStubGenerator)->generatedJITCode().addressForCall()); 134 Jump failed = branchTestPtr(Zero, regT0); 135 emitPutVirtualRegister(dst, regT0); 136 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); 137 failed.link(this); 138 notString.link(this); 139 nonCell.link(this); 140 141 linkSlowCase(iter); // vector length check 142 linkSlowCase(iter); // empty value 143 144 JITStubCall stubCall(this, cti_op_get_by_val); 145 stubCall.addArgument(base, regT2); 146 stubCall.addArgument(property, regT2); 147 stubCall.call(dst); 84 148 } 85 149 -
trunk/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r55564 r59056 270 270 #endif 271 271 272 PassRefPtr<NativeExecutable> JIT::stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool) 273 { 274 JSInterfaceJIT jit; 275 JumpList failures; 276 failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr))); 277 failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount)))); 278 279 // Load string length to regT1, and start the process of loading the data pointer into regT0 280 jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1); 281 jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0); 282 jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0); 283 284 // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large 285 failures.append(jit.branch32(AboveOrEqual, regT2, regT1)); 286 287 // Load the character 288 jit.load16(BaseIndex(regT0, regT2, TimesTwo, 0), regT0); 289 290 failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100))); 291 jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1); 292 jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0); 293 jit.move(Imm32(JSValue::CellTag), regT1); // We null check regT0 on return so this is safe 294 jit.ret(); 295 296 failures.link(&jit); 297 jit.move(Imm32(0), regT0); 298 jit.ret(); 299 300 LinkBuffer patchBuffer(&jit, pool); 301 return adoptRef(new NativeExecutable(patchBuffer.finalizeCode())); 302 } 303 272 304 void JIT::emit_op_get_by_val(Instruction* currentInstruction) 273 305 { … … 301 333 linkSlowCase(iter); // property int32 check 302 334 linkSlowCaseIfNotJSCell(iter, base); // base cell check 335 336 Jump nonCell = jump(); 303 337 linkSlowCase(iter); // base array check 338 Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)); 339 emitNakedCall(m_globalData->getThunk(stringGetByValStubGenerator)->generatedJITCode().addressForCall()); 340 Jump failed = branchTestPtr(Zero, regT0); 341 emitStore(dst, regT1, regT0); 342 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val)); 343 failed.link(this); 344 notString.link(this); 345 nonCell.link(this); 346 304 347 linkSlowCase(iter); // vector length check 305 348 linkSlowCase(iter); // empty value -
trunk/JavaScriptCore/jit/JSInterfaceJIT.h
r58902 r59056 170 170 Jump emitJumpIfImmediateNumber(RegisterID reg); 171 171 Jump emitJumpIfNotImmediateNumber(RegisterID reg); 172 void emitFastArithImmToInt(RegisterID reg); 172 173 #endif 173 174 … … 261 262 return notNumber; 262 263 } 263 264 265 ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID) 266 { 267 } 268 264 269 #endif 265 270 … … 284 289 return jump(); 285 290 } 291 292 ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID reg) 293 { 294 rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg); 295 } 296 286 297 #endif 287 298
Note:
See TracChangeset
for help on using the changeset viewer.