📄 jitpropertyaccess.cpp
字号:
// Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); jumpLocation.relink(entryLabel);}void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame){ // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is // referencing the prototype object - let's speculatively load it's table nice and early!) JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; loadPtr(protoPropertyStorage, regT1); // Check eax is an object of the right Structure. Jump failureCases1 = checkStructure(regT0, structure); // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure);#if PLATFORM(X86_64) move(ImmPtr(prototypeStructure), regT3); Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);#else Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));#endif // Checks out okay! - getDirectOffset loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0); Jump success = jump(); void* code = m_assembler.executableCopy(m_codeBlock->executablePool()); PatchBuffer patchBuffer(code); // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; patchBuffer.link(failureCases1, lastProtoBegin); patchBuffer.link(failureCases2, lastProtoBegin); // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); CodeLocationLabel entryLabel = patchBuffer.entry(); structure->ref(); prototypeStructure->ref(); prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure); // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); jumpLocation.relink(entryLabel);}void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame){ ASSERT(count); JumpList bucketsOfFail; // Check eax is an object of the right Structure. Jump baseObjectCheck = checkStructure(regT0, structure); bucketsOfFail.append(baseObjectCheck); Structure* currStructure = structure; RefPtr<Structure>* chainEntries = chain->head(); JSObject* protoObject = 0; for (unsigned i = 0; i < count; ++i) { protoObject = asObject(currStructure->prototypeForLookup(callFrame)); currStructure = chainEntries[i].get(); // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure);#if PLATFORM(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));#else bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));#endif } ASSERT(protoObject); PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; loadPtr(protoPropertyStorage, regT1); loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0); Jump success = jump(); void* code = m_assembler.executableCopy(m_codeBlock->executablePool()); PatchBuffer patchBuffer(code); // Use the patch information to link the failure cases back to the original slow case routine. CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine; patchBuffer.link(bucketsOfFail, lastProtoBegin); // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); CodeLocationLabel entryLabel = patchBuffer.entry(); // Track the stub we have created so that it will be deleted later. structure->ref(); chain->ref(); prototypeStructures->list[currentIndex].set(entryLabel, structure, chain); // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); jumpLocation.relink(entryLabel);}#endifvoid JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame){#if USE(CTI_REPATCH_PIC) // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. returnAddress.relinkCallerToFunction(JITStubs::cti_op_get_by_id_proto_list); ASSERT(count); JumpList bucketsOfFail; // Check eax is an object of the right Structure. bucketsOfFail.append(checkStructure(regT0, structure)); Structure* currStructure = structure; RefPtr<Structure>* chainEntries = chain->head(); JSObject* protoObject = 0; for (unsigned i = 0; i < count; ++i) { protoObject = asObject(currStructure->prototypeForLookup(callFrame)); currStructure = chainEntries[i].get(); // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure);#if PLATFORM(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));#else bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));#endif } ASSERT(protoObject); PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; loadPtr(protoPropertyStorage, regT1); loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0); Jump success = jump(); void* code = m_assembler.executableCopy(m_codeBlock->executablePool()); PatchBuffer patchBuffer(code); // Use the patch information to link the failure cases back to the original slow case routine. patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall)); // On success return back to the hot patch code, at a point it will perform the store to dest for us. patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); // Track the stub we have created so that it will be deleted later. CodeLocationLabel entryLabel = patchBuffer.entry(); stubInfo->stubRoutine = entryLabel; // Finally patch the jump to slow case back in the hot path to jump here instead. CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); jumpLocation.relink(entryLabel);#else ASSERT(count); JumpList bucketsOfFail; // Check eax is an object of the right Structure. bucketsOfFail.append(emitJumpIfNotJSCell(regT0)); bucketsOfFail.append(checkStructure(regT0, structure)); Structure* currStructure = structure; RefPtr<Structure>* chainEntries = chain->head(); JSObject* protoObject = 0; for (unsigned i = 0; i < count; ++i) { protoObject = asObject(currStructure->prototypeForLookup(callFrame)); currStructure = chainEntries[i].get(); // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure);#if PLATFORM(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, regT3, AbsoluteAddress(prototypeStructureAddress)));#else bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));#endif } ASSERT(protoObject); PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; loadPtr(protoPropertyStorage, regT1); loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0); ret(); void* code = m_assembler.executableCopy(m_codeBlock->executablePool()); patchBuffer.link(bucketsOfFail, JITStubs::cti_op_get_by_id_proto_fail); stubInfo->stubRoutine = patchBuffer.entry(); returnAddress.relinkCallerToFunction(code);#endif}void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress){ // Check eax is an object of the right Structure. Jump failureCases1 = emitJumpIfNotJSCell(regT0); Jump failureCases2 = checkStructure(regT0, structure); // checks out okay! - putDirectOffset loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0); storePtr(regT1, Address(regT0, cachedOffset * sizeof(JSValuePtr))); ret(); Call failureCases1Call = makeTailRecursiveCall(failureCases1); Call failureCases2Call = makeTailRecursiveCall(failureCases2); void* code = m_assembler.executableCopy(m_codeBlock->executablePool()); PatchBuffer patchBuffer(code); patchBuffer.link(failureCases1Call, JITStubs::cti_op_put_by_id_fail); patchBuffer.link(failureCases2Call, JITStubs::cti_op_put_by_id_fail); stubInfo->stubRoutine = patchBuffer.entry(); returnAddress.relinkCallerToFunction(code);}#endif} // namespace JSC#endif // ENABLE(JIT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -