Changeset 40846 in webkit for trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
- Timestamp:
- Feb 10, 2009, 8:57:08 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r40562 r40846 135 135 emitPutJITStubArg(X86::eax, 1); 136 136 emitPutJITStubArgConstant(ident, 2); 137 Jumpcall = emitCTICall(Interpreter::cti_op_get_by_id);137 Call call = emitCTICall(Interpreter::cti_op_get_by_id); 138 138 emitPutVirtualRegister(resultVReg); 139 139 … … 177 177 emitPutJITStubArg(X86::eax, 1); 178 178 emitPutJITStubArg(X86::edx, 3); 179 Jumpcall = emitCTICall(Interpreter::cti_op_put_by_id);179 Call call = emitCTICall(Interpreter::cti_op_put_by_id); 180 180 181 181 // Track the location of the call; this will be used to recover patch information. … … 194 194 } 195 195 196 void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void*returnAddress)196 void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ProcessorReturnAddress returnAddress) 197 197 { 198 198 JumpList failureCases; … … 224 224 successCases.link(this); 225 225 226 JumpcallTarget;226 Call callTarget; 227 227 228 228 // emit a call only if storage realloc is needed … … 270 270 271 271 if (plantedFailureJump) 272 patchBuffer.link (failureJump, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));272 patchBuffer.linkTailRecursive(failureJump, Interpreter::cti_op_put_by_id_fail); 273 273 274 274 if (transitionWillNeedStorageRealloc(oldStructure, newStructure)) 275 patchBuffer.link(callTarget, re interpret_cast<void*>(resizePropertyStorage));275 patchBuffer.link(callTarget, resizePropertyStorage); 276 276 277 stubInfo->stubRoutine = code;278 279 Jump::patch(returnAddress,code);280 } 281 282 void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void*returnAddress)277 stubInfo->stubRoutine = patchBuffer.entry(); 278 279 returnAddress.relinkCallerToFunction(code); 280 } 281 282 void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress) 283 283 { 284 284 // We don't want to patch more than once - in future go to cti_op_get_by_id_generic. 285 285 // Should probably go to Interpreter::cti_op_get_by_id_fail, but that doesn't do anything interesting right now. 286 Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));286 returnAddress.relinkCallerToFunction(Interpreter::cti_op_get_by_id_self_fail); 287 287 288 288 // Patch the offset into the propoerty map to load from, then patch the Structure to look for. 289 void* structureAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdStructure); 290 void* displacementAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPropertyMapOffset); 291 DataLabelPtr::patch(structureAddress, structure); 292 DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr)); 293 } 294 295 void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress) 289 stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure).repatch(structure); 290 stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset).repatch(cachedOffset * sizeof(JSValuePtr)); 291 } 292 293 void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress) 296 294 { 297 295 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 298 296 // Should probably go to Interpreter::cti_op_put_by_id_fail, but that doesn't do anything interesting right now. 299 Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_generic));297 returnAddress.relinkCallerToFunction(Interpreter::cti_op_put_by_id_generic); 300 298 301 299 // Patch the offset into the propoerty map to load from, then patch the Structure to look for. 302 void* structureAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdStructure; 303 void* displacementAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdPropertyMapOffset; 304 DataLabelPtr::patch(structureAddress, structure); 305 DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr)); 306 } 307 308 void JIT::privateCompilePatchGetArrayLength(void* returnAddress) 300 stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure).repatch(structure); 301 stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset).repatch(cachedOffset * sizeof(JSValuePtr)); 302 } 303 304 void JIT::privateCompilePatchGetArrayLength(ProcessorReturnAddress returnAddress) 309 305 { 310 306 StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress); 311 307 312 308 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 313 Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));309 returnAddress.relinkCallerToFunction(Interpreter::cti_op_get_by_id_array_fail); 314 310 315 311 // Check eax is an array … … 329 325 330 326 // Use the patch information to link the failure cases back to the original slow case routine. 331 void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;327 CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); 332 328 patchBuffer.link(failureCases1, slowCaseBegin); 333 329 patchBuffer.link(failureCases2, slowCaseBegin); 334 330 335 331 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 336 void* hotPathPutResult = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult; 337 patchBuffer.link(success, hotPathPutResult); 332 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 338 333 339 334 // Track the stub we have created so that it will be deleted later. 340 stubInfo->stubRoutine = code; 341 342 // Finally patch the jump to sow case back in the hot path to jump here instead. 343 void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase; 344 Jump::patch(jumpLocation, code); 345 } 346 347 void JIT::privateCompileGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress) 335 CodeLocationLabel entryLabel = patchBuffer.entry(); 336 stubInfo->stubRoutine = entryLabel; 337 338 // Finally patch the jump to slow case back in the hot path to jump here instead. 339 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 340 jumpLocation.relink(entryLabel); 341 } 342 343 void JIT::privateCompileGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress) 348 344 { 349 345 // Check eax is an object of the right Structure. … … 359 355 PatchBuffer patchBuffer(code); 360 356 361 patchBuffer.link (failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));362 patchBuffer.link (failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));363 364 stubInfo->stubRoutine = code;365 366 Jump::patch(returnAddress,code);367 } 368 369 void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void*returnAddress, CallFrame* callFrame)357 patchBuffer.linkTailRecursive(failureCases1, Interpreter::cti_op_get_by_id_self_fail); 358 patchBuffer.linkTailRecursive(failureCases2, Interpreter::cti_op_get_by_id_self_fail); 359 360 stubInfo->stubRoutine = patchBuffer.entry(); 361 362 returnAddress.relinkCallerToFunction(code); 363 } 364 365 void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame) 370 366 { 371 367 #if USE(CTI_REPATCH_PIC) 372 368 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 373 Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));369 returnAddress.relinkCallerToFunction(Interpreter::cti_op_get_by_id_proto_list); 374 370 375 371 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is … … 400 396 401 397 // Use the patch information to link the failure cases back to the original slow case routine. 402 void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;398 CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); 403 399 patchBuffer.link(failureCases1, slowCaseBegin); 404 400 patchBuffer.link(failureCases2, slowCaseBegin); 405 401 406 402 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 407 intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult; 408 patchBuffer.link(success, reinterpret_cast<void*>(successDest)); 403 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 409 404 410 405 // Track the stub we have created so that it will be deleted later. 411 stubInfo->stubRoutine = code; 406 CodeLocationLabel entryLabel = patchBuffer.entry(); 407 stubInfo->stubRoutine = entryLabel; 412 408 413 409 // Finally patch the jump to slow case back in the hot path to jump here instead. 414 void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;415 Jump::patch(jumpLocation, code);410 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 411 jumpLocation.relink(entryLabel); 416 412 #else 417 413 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is … … 437 433 PatchBuffer patchBuffer(code); 438 434 439 patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));440 patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));441 patchBuffer.link(failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));442 443 stubInfo->stubRoutine = code;444 445 Jump::patch(returnAddress,code);435 patchBuffer.link(failureCases1, Interpreter::cti_op_get_by_id_proto_fail); 436 patchBuffer.link(failureCases2, Interpreter::cti_op_get_by_id_proto_fail); 437 patchBuffer.link(failureCases3, Interpreter::cti_op_get_by_id_proto_fail); 438 439 stubInfo->stubRoutine = patchBuffer.entry(); 440 441 returnAddress.relinkCallerToFunction(code); 446 442 #endif 447 443 } … … 460 456 461 457 // Use the patch information to link the failure cases back to the original slow case routine. 462 void*lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;458 CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine; 463 459 if (!lastProtoBegin) 464 lastProtoBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;460 lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall); 465 461 466 462 patchBuffer.link(failureCase, lastProtoBegin); 467 463 468 464 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 469 intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult; 470 patchBuffer.link(success, reinterpret_cast<void*>(successDest)); 465 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 466 467 CodeLocationLabel entryLabel = patchBuffer.entry(); 471 468 472 469 structure->ref(); 473 polymorphicStructures->list[currentIndex].set( code, structure);470 polymorphicStructures->list[currentIndex].set(entryLabel, structure); 474 471 475 472 // Finally patch the jump to slow case back in the hot path to jump here instead. 476 void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;477 Jump::patch(jumpLocation, code);473 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 474 jumpLocation.relink(entryLabel); 478 475 } 479 476 … … 507 504 508 505 // Use the patch information to link the failure cases back to the original slow case routine. 509 void*lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;506 CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; 510 507 patchBuffer.link(failureCases1, lastProtoBegin); 511 508 patchBuffer.link(failureCases2, lastProtoBegin); 512 509 513 510 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 514 intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult; 515 patchBuffer.link(success, reinterpret_cast<void*>(successDest)); 511 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 512 513 CodeLocationLabel entryLabel = patchBuffer.entry(); 516 514 517 515 structure->ref(); 518 516 prototypeStructure->ref(); 519 prototypeStructures->list[currentIndex].set( code, structure, prototypeStructure);517 prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure); 520 518 521 519 // Finally patch the jump to slow case back in the hot path to jump here instead. 522 void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;523 Jump::patch(jumpLocation, code);520 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 521 jumpLocation.relink(entryLabel); 524 522 } 525 523 … … 561 559 562 560 // Use the patch information to link the failure cases back to the original slow case routine. 563 void*lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;561 CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; 564 562 565 563 patchBuffer.link(bucketsOfFail, lastProtoBegin); 566 564 567 565 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 568 intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult; 569 patchBuffer.link(success, reinterpret_cast<void*>(successDest)); 566 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 567 568 CodeLocationLabel entryLabel = patchBuffer.entry(); 570 569 571 570 // Track the stub we have created so that it will be deleted later. 572 571 structure->ref(); 573 572 chain->ref(); 574 prototypeStructures->list[currentIndex].set( code, structure, chain);573 prototypeStructures->list[currentIndex].set(entryLabel, structure, chain); 575 574 576 575 // Finally patch the jump to slow case back in the hot path to jump here instead. 577 void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;578 Jump::patch(jumpLocation, code);579 } 580 #endif 581 582 void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void*returnAddress, CallFrame* callFrame)576 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 577 jumpLocation.relink(entryLabel); 578 } 579 #endif 580 581 void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame) 583 582 { 584 583 #if USE(CTI_REPATCH_PIC) 585 584 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 586 Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));585 returnAddress.relinkCallerToFunction(Interpreter::cti_op_get_by_id_proto_list); 587 586 588 587 ASSERT(count); … … 620 619 621 620 // Use the patch information to link the failure cases back to the original slow case routine. 622 void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall; 623 624 patchBuffer.link(bucketsOfFail, slowCaseBegin); 621 patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall)); 625 622 626 623 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 627 intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult; 628 patchBuffer.link(success, reinterpret_cast<void*>(successDest)); 624 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 629 625 630 626 // Track the stub we have created so that it will be deleted later. 631 stubInfo->stubRoutine = code; 627 CodeLocationLabel entryLabel = patchBuffer.entry(); 628 stubInfo->stubRoutine = entryLabel; 632 629 633 630 // Finally patch the jump to slow case back in the hot path to jump here instead. 634 void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;635 Jump::patch(jumpLocation, code);631 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 632 jumpLocation.relink(entryLabel); 636 633 #else 637 634 ASSERT(count); … … 668 665 void* code = m_assembler.executableCopy(m_codeBlock->executablePool()); 669 666 670 patchBuffer.link(bucketsOfFail, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));671 672 stubInfo->stubRoutine = code;673 674 Jump::patch(returnAddress,code);675 #endif 676 } 677 678 void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void*returnAddress)667 patchBuffer.link(bucketsOfFail, Interpreter::cti_op_get_by_id_proto_fail); 668 669 stubInfo->stubRoutine = patchBuffer.entry(); 670 671 returnAddress.relinkCallerToFunction(code); 672 #endif 673 } 674 675 void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress) 679 676 { 680 677 // Check eax is an object of the right Structure. … … 690 687 PatchBuffer patchBuffer(code); 691 688 692 patchBuffer.link (failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));693 patchBuffer.link (failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));694 695 stubInfo->stubRoutine = code;689 patchBuffer.linkTailRecursive(failureCases1, Interpreter::cti_op_put_by_id_fail); 690 patchBuffer.linkTailRecursive(failureCases2, Interpreter::cti_op_put_by_id_fail); 691 692 stubInfo->stubRoutine = patchBuffer.entry(); 696 693 697 Jump::patch(returnAddress,code);694 returnAddress.relinkCallerToFunction(code); 698 695 } 699 696
Note:
See TracChangeset
for help on using the changeset viewer.