When we are rebuilding 'typeInst' and we want to make sure that we rebuild all the methods that were actively referenced previously, this method will generate BfMethodSpecializationRequest for all used methods from previously-built modules
| 3048 | // actively referenced previously, this method will generate BfMethodSpecializationRequest for all used |
| 3049 | // methods from previously-built modules |
| 3050 | void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkSpecializedMethodRebuildFlag) |
| 3051 | { |
| 3052 | BF_ASSERT(!typeInst->IsDeleting()); |
| 3053 | |
| 3054 | BP_ZONE("BfContext::QueueMethodSpecializations"); |
| 3055 | |
| 3056 | auto module = typeInst->mModule; |
| 3057 | if (module == NULL) |
| 3058 | return; |
| 3059 | |
| 3060 | BfLogSysM("QueueMethodSpecializations typeInst %p module %p\n", typeInst, module); |
| 3061 | |
| 3062 | if (!checkSpecializedMethodRebuildFlag) |
| 3063 | { |
| 3064 | // Modules that have already rebuilt have already explicitly added their method specialization requests. |
| 3065 | // This pass is just for handling rebuilding old specialization requests |
| 3066 | if (module->mRevision == mCompiler->mRevision) |
| 3067 | return; |
| 3068 | } |
| 3069 | |
| 3070 | // Find any method specialization requests for types that are rebuilding, but from |
| 3071 | // modules that are NOT rebuilding to be sure we generate those. Failure to do this |
| 3072 | // will cause a link error from an old module |
| 3073 | for (auto& methodRefKV : typeInst->mSpecializedMethodReferences) |
| 3074 | { |
| 3075 | auto& methodRef = methodRefKV.mKey; |
| 3076 | auto& specializedMethodRefInfo = methodRefKV.mValue; |
| 3077 | |
| 3078 | if (checkSpecializedMethodRebuildFlag) |
| 3079 | { |
| 3080 | if ((methodRef.mTypeInstance->mRebuildFlags & BfTypeRebuildFlag_SpecializedMethodRebuild) == 0) |
| 3081 | continue; |
| 3082 | } |
| 3083 | else |
| 3084 | { |
| 3085 | if ((methodRef.mTypeInstance->mModule == NULL) || |
| 3086 | (methodRef.mTypeInstance->mModule->mRevision != mCompiler->mRevision)) |
| 3087 | continue; |
| 3088 | } |
| 3089 | |
| 3090 | bool allowMismatch = false; |
| 3091 | if ((methodRef.mTypeInstance->IsInstanceOf(mCompiler->mInternalTypeDef)) || (methodRef.mTypeInstance->IsInstanceOf(mCompiler->mGCTypeDef))) |
| 3092 | allowMismatch = true; |
| 3093 | |
| 3094 | // The signature hash better not have changed, because if it did then we should have rebuilding 'module' |
| 3095 | // because of dependencies! This infers a dependency error. |
| 3096 | int newSignatureHash = (int)methodRef.mTypeInstance->mTypeDef->mSignatureHash; |
| 3097 | BF_ASSERT((newSignatureHash == methodRef.mSignatureHash) || (allowMismatch)); |
| 3098 | |
| 3099 | BfMethodDef* methodDef = NULL; |
| 3100 | if (methodRef.mMethodNum < methodRef.mTypeInstance->mTypeDef->mMethods.mSize) |
| 3101 | methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum]; |
| 3102 | |
| 3103 | auto targetContext = methodRef.mTypeInstance->mContext; |
| 3104 | BfMethodSpecializationRequest* specializationRequest = targetContext->mMethodSpecializationWorkList.Alloc(); |
| 3105 | if (specializedMethodRefInfo.mHasReifiedRef) |
| 3106 | specializationRequest->mFromModule = typeInst->mModule; |
| 3107 | else |
no test coverage detected