Changeset 49065 in webkit for trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
- Timestamp:
- Oct 3, 2009, 10:01:14 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r49030 r49065 274 274 emitJumpSlowCaseIfNotJSCell(base, regT1); 275 275 addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); 276 addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); 277 278 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0); 279 load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag 280 load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload 276 277 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); 278 addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); 279 280 load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag 281 load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload 282 addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag))); 283 281 284 emitStore(dst, regT1, regT0); 282 285 map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); … … 289 292 unsigned property = currentInstruction[3].u.operand; 290 293 291 // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here.292 Label callGetByValJITStub(this);293 294 294 linkSlowCase(iter); // property int32 check 295 295 linkSlowCaseIfNotJSCell(iter, base); // base cell check 296 296 linkSlowCase(iter); // base array check 297 linkSlowCase(iter); // vector length check 298 linkSlowCase(iter); // empty value 297 299 298 300 JITStubCall stubCall(this, cti_op_get_by_val); … … 300 302 stubCall.addArgument(property); 301 303 stubCall.call(dst); 302 303 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));304 305 linkSlowCase(iter); // array fast cut-off check306 307 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0);308 branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), callGetByValJITStub);309 310 // Missed the fast region, but it is still in the vector.311 load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag312 load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload313 branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)).linkTo(callGetByValJITStub, this);314 315 emitStore(dst, regT1, regT0);316 304 } 317 305 … … 327 315 emitJumpSlowCaseIfNotJSCell(base, regT1); 328 316 addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); 317 addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); 318 329 319 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3); 330 320 331 Jump inFastVector = branch32(Below, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); 332 333 // Check if the access is within the vector. 334 addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); 335 336 // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. 337 // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 338 addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag))); 339 340 inFastVector.link(this); 341 321 Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag)); 322 323 Label storeResult(this); 342 324 emitLoad(value, regT1, regT0); 343 325 store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); // payload 344 326 store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4)); // tag 327 Jump end = jump(); 328 329 empty.link(this); 330 add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); 331 branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); 332 333 add32(Imm32(1), regT2, regT0); 334 store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))); 335 jump().linkTo(storeResult, this); 336 337 end.link(this); 345 338 } 346 339 … … 354 347 linkSlowCaseIfNotJSCell(iter, base); // base cell check 355 348 linkSlowCase(iter); // base not array check 349 linkSlowCase(iter); // in vector check 356 350 357 351 JITStubCall stubPutByValCall(this, cti_op_put_by_val); … … 360 354 stubPutByValCall.addArgument(value); 361 355 stubPutByValCall.call(); 362 363 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));364 365 // Slow cases for immediate int accesses to arrays.366 linkSlowCase(iter); // in vector check367 linkSlowCase(iter); // written to slot check368 369 JITStubCall stubCall(this, cti_op_put_by_val_array);370 stubCall.addArgument(regT1, regT0);371 stubCall.addArgument(regT2);372 stubCall.addArgument(value);373 stubCall.call();374 356 } 375 357 … … 953 935 void JIT::emit_op_get_by_val(Instruction* currentInstruction) 954 936 { 955 emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1); 937 unsigned dst = currentInstruction[1].u.operand; 938 unsigned base = currentInstruction[2].u.operand; 939 unsigned property = currentInstruction[3].u.operand; 940 941 emitGetVirtualRegisters(base, regT0, property, regT1); 956 942 emitJumpSlowCaseIfNotImmediateInteger(regT1); 957 943 #if USE(JSVALUE64) 958 944 // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter. 959 // We check the value as if it was a uint32 against the m_ fastAccessCutoff- which will always fail if960 // number was signed since m_ fastAccessCutoffis always less than intmax (since the total allocation945 // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if 946 // number was signed since m_vectorLength is always less than intmax (since the total allocation 961 947 // size is always less than 4Gb). As such zero extending wil have been correct (and extending the value 962 948 // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign … … 966 952 emitFastArithImmToInt(regT1); 967 953 #endif 968 emitJumpSlowCaseIfNotJSCell(regT0 );954 emitJumpSlowCaseIfNotJSCell(regT0, base); 969 955 addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); 970 956 971 // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff972 957 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); 973 addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)))); 974 975 // Get the value from the vector 958 addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); 959 976 960 loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); 977 emitPutVirtualRegister(currentInstruction[1].u.operand); 961 addSlowCase(branchTestPtr(Zero, regT0)); 962 963 emitPutVirtualRegister(dst); 978 964 } 979 965 980 966 void JIT::emit_op_put_by_val(Instruction* currentInstruction) 981 967 { 982 emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1); 968 unsigned base = currentInstruction[1].u.operand; 969 unsigned property = currentInstruction[2].u.operand; 970 unsigned value = currentInstruction[3].u.operand; 971 972 emitGetVirtualRegisters(base, regT0, property, regT1); 983 973 emitJumpSlowCaseIfNotImmediateInteger(regT1); 984 974 #if USE(JSVALUE64) … … 988 978 emitFastArithImmToInt(regT1); 989 979 #endif 990 emitJumpSlowCaseIfNotJSCell(regT0 );980 emitJumpSlowCaseIfNotJSCell(regT0, base); 991 981 addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr))); 992 993 // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff 982 addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength)))); 983 994 984 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2); 995 Jump inFastVector = branch32(Below, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))); 996 // No; oh well, check if the access if within the vector - if so, we may still be okay. 997 addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)))); 998 999 // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location. 1000 // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 1001 addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])))); 1002 1003 // All good - put the value into the array. 1004 inFastVector.link(this); 1005 emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); 985 986 Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); 987 988 Label storeResult(this); 989 emitGetVirtualRegister(value, regT0); 1006 990 storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); 991 Jump end = jump(); 992 993 empty.link(this); 994 add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); 995 branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this); 996 997 move(regT1, regT0); 998 add32(Imm32(1), regT0); 999 store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))); 1000 jump().linkTo(storeResult, this); 1001 1002 end.link(this); 1007 1003 } 1008 1004
Note:
See TracChangeset
for help on using the changeset viewer.