| 26042 | } |
| 26043 | |
| 26044 | void BfModule::UniqueSlotVirtualMethod(BfMethodInstance* methodInstance) |
| 26045 | { |
| 26046 | BF_ASSERT(methodInstance->GetOwner() == mCurTypeInstance); |
| 26047 | |
| 26048 | auto typeInstance = mCurTypeInstance; |
| 26049 | auto methodDef = methodInstance->mMethodDef; |
| 26050 | |
| 26051 | int virtualMethodMatchIdx = -1; |
| 26052 | |
| 26053 | if (typeInstance->mHotTypeData != NULL) |
| 26054 | { |
| 26055 | if (typeInstance->mHotTypeData->mVTableOrigLength != -1) |
| 26056 | { |
| 26057 | BF_ASSERT(mCompiler->IsHotCompile()); |
| 26058 | // In the 'normal' case we'd assert that mIsOverride is false, but if we can't find the declaring method then we |
| 26059 | // may slot this override anyway (?) |
| 26060 | |
| 26061 | int vTableStart = 0; |
| 26062 | auto implBaseType = typeInstance->GetImplBaseType(); |
| 26063 | if (implBaseType != NULL) |
| 26064 | vTableStart = implBaseType->mVirtualMethodTableSize; |
| 26065 | |
| 26066 | StringT<512> mangledName; |
| 26067 | BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), methodInstance); |
| 26068 | for (int checkIdxOfs = 0; checkIdxOfs < (int)typeInstance->mHotTypeData->mVTableEntries.size(); checkIdxOfs++) |
| 26069 | { |
| 26070 | // O(1) checking when virtual methods haven't changed |
| 26071 | int checkIdx = (typeInstance->mVirtualMethodTableSize - vTableStart + checkIdxOfs) % (int)typeInstance->mHotTypeData->mVTableEntries.size(); |
| 26072 | |
| 26073 | auto& entry = typeInstance->mHotTypeData->mVTableEntries[checkIdx]; |
| 26074 | if (mangledName == entry.mFuncName) |
| 26075 | { |
| 26076 | virtualMethodMatchIdx = vTableStart + checkIdx; |
| 26077 | break; |
| 26078 | } |
| 26079 | } |
| 26080 | |
| 26081 | if (virtualMethodMatchIdx != -1) |
| 26082 | { |
| 26083 | methodInstance->mVirtualTableIdx = virtualMethodMatchIdx; |
| 26084 | typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod = methodInstance; |
| 26085 | typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = methodInstance; |
| 26086 | } |
| 26087 | typeInstance->mVirtualMethodTableSize = (int)typeInstance->mVirtualMethodTable.size(); |
| 26088 | } |
| 26089 | } |
| 26090 | |
| 26091 | if (virtualMethodMatchIdx == -1) |
| 26092 | { |
| 26093 | methodInstance->mVirtualTableIdx = typeInstance->mVirtualMethodTableSize++; |
| 26094 | BfVirtualMethodEntry entry = { methodInstance, methodInstance }; |
| 26095 | typeInstance->mVirtualMethodTable.push_back(entry); |
| 26096 | } |
| 26097 | } |
| 26098 | |
| 26099 | void BfModule::CompareDeclTypes(BfTypeInstance* typeInst, BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse) |
| 26100 | { |
nothing calls this directly
no test coverage detected