⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jitpropertyaccess.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        callTarget = call();#else        push(Imm32(newStructure->propertyStorageCapacity()));        push(Imm32(oldStructure->propertyStorageCapacity()));        push(regT0);        callTarget = call();        addPtr(Imm32(3 * sizeof(void*)), X86::esp);#endif        emitGetJITStubArg(3, regT1);        push(X86::ebx);    }    // Assumes m_refCount can be decremented easily, refcount decrement is safe as     // codeblock should ensure oldStructure->m_refCount > 0    sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));    add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));    storePtr(ImmPtr(newStructure), Address(regT0, FIELD_OFFSET(JSCell, m_structure)));    // write the value    loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);    storePtr(regT1, Address(regT0, cachedOffset * sizeof(JSValuePtr)));    ret();        ASSERT(!failureCases.empty());    failureCases.link(this);    restoreArgumentReferenceForTrampoline();    Call failureCall = tailRecursiveCall();    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());    PatchBuffer patchBuffer(code);    patchBuffer.link(failureCall, JITStubs::cti_op_put_by_id_fail);    if (willNeedStorageRealloc)        patchBuffer.link(callTarget, resizePropertyStorage);        stubInfo->stubRoutine = patchBuffer.entry();    returnAddress.relinkCallerToFunction(code);}void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress){    // We don't want to patch more than once - in future go to cti_op_get_by_id_generic.    // Should probably go to JITStubs::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.    returnAddress.relinkCallerToFunction(JITStubs::cti_op_get_by_id_self_fail);    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.    stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure).repatch(structure);    stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset).repatch(cachedOffset * sizeof(JSValuePtr));}void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress){    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.    // Should probably go to JITStubs::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.    returnAddress.relinkCallerToFunction(JITStubs::cti_op_put_by_id_generic);    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.    stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure).repatch(structure);    stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset).repatch(cachedOffset * sizeof(JSValuePtr));}void JIT::privateCompilePatchGetArrayLength(ProcessorReturnAddress returnAddress){    StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);    // 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_array_fail);    // Check eax is an array    Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));    // Checks out okay! - get the length from the storage    loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);    load32(Address(regT2, FIELD_OFFSET(ArrayStorage, m_length)), regT2);    Jump failureCases2 = branch32(Above, regT2, Imm32(JSImmediate::maxImmediateInt));    emitFastArithIntToImmNoCheck(regT2, 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 slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);    patchBuffer.link(failureCases1, slowCaseBegin);    patchBuffer.link(failureCases2, slowCaseBegin);    // 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);}void JIT::privateCompileGetByIdSelf(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! - getDirectOffset    loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);    loadPtr(Address(regT0, cachedOffset * sizeof(JSValuePtr)), regT0);    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_get_by_id_self_fail);    patchBuffer.link(failureCases2Call, JITStubs::cti_op_get_by_id_self_fail);    stubInfo->stubRoutine = patchBuffer.entry();    returnAddress.relinkCallerToFunction(code);}void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, 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);    // 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(static_cast<void*>(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 slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);    patchBuffer.link(failureCases1, slowCaseBegin);    patchBuffer.link(failureCases2, slowCaseBegin);    // 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    // 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 = emitJumpIfNotJSCell(regT0);    Jump failureCases2 = checkStructure(regT0, structure);    // Check the prototype object's Structure had not changed.    Structure** prototypeStructureAddress = &(protoObject->m_structure);    Jump failureCases3 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));    // Checks out okay! - getDirectOffset    loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);    ret();    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());    PatchBuffer patchBuffer(code);    patchBuffer.link(failureCases1, JITStubs::cti_op_get_by_id_proto_fail);    patchBuffer.link(failureCases2, JITStubs::cti_op_get_by_id_proto_fail);    patchBuffer.link(failureCases3, JITStubs::cti_op_get_by_id_proto_fail);    stubInfo->stubRoutine = patchBuffer.entry();    returnAddress.relinkCallerToFunction(code);#endif}#if USE(CTI_REPATCH_PIC)void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset){    Jump failureCase = checkStructure(regT0, structure);    loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);    loadPtr(Address(regT0, cachedOffset * sizeof(JSValuePtr)), regT0);    Jump success = jump();    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());    ASSERT(code);    PatchBuffer patchBuffer(code);    // Use the patch information to link the failure cases back to the original slow case routine.    CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;    if (!lastProtoBegin)        lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);    patchBuffer.link(failureCase, 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();    polymorphicStructures->list[currentIndex].set(entryLabel, structure);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -