| 927 | } |
| 928 | |
| 929 | void BfModule::EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail) |
| 930 | { |
| 931 | int64 collisionId = 0; |
| 932 | |
| 933 | struct _CallInfo |
| 934 | { |
| 935 | BfModuleMethodInstance mModuleMethodInstance; |
| 936 | bool mBypassVirtual; |
| 937 | bool mIsAllocaFunc; |
| 938 | }; |
| 939 | |
| 940 | //typedef std::map<int64, _CallInfo> MapType; |
| 941 | //MapType methodInstanceMap; |
| 942 | Dictionary<int64, _CallInfo> methodInstanceMap; |
| 943 | int blockCount = 0; |
| 944 | |
| 945 | HashSet<BfMethodInstance*> nullCheckMethodSet; |
| 946 | |
| 947 | BfDeferredCallEntry* deferredCallEntry = callEntries.mHead; |
| 948 | while (deferredCallEntry != NULL) |
| 949 | { |
| 950 | BfModuleMethodInstance moduleMethodInstance = deferredCallEntry->mModuleMethodInstance; |
| 951 | int64 methodId = 0; |
| 952 | if (moduleMethodInstance.mMethodInstance != NULL) |
| 953 | { |
| 954 | int64 idHash = moduleMethodInstance.mMethodInstance->mIdHash; |
| 955 | auto deferredMethodCallData = mDeferredMethodCallData[moduleMethodInstance.mMethodInstance]; |
| 956 | BF_ASSERT(deferredMethodCallData->mMethodId != 0); |
| 957 | //methodInstanceMap[deferredMethodCallData->mMethodId] = moduleMethodInstance; |
| 958 | _CallInfo* callInfo = NULL; |
| 959 | if (methodInstanceMap.TryAdd(deferredMethodCallData->mMethodId, NULL, &callInfo)) |
| 960 | { |
| 961 | callInfo->mModuleMethodInstance = moduleMethodInstance; |
| 962 | callInfo->mBypassVirtual = deferredCallEntry->mBypassVirtual; |
| 963 | callInfo->mIsAllocaFunc = deferredCallEntry->mIsAllocaFunc; |
| 964 | } |
| 965 | else |
| 966 | { |
| 967 | // Only bypass virtual if ALL these calls are devirtualized |
| 968 | callInfo->mBypassVirtual &= deferredCallEntry->mBypassVirtual; |
| 969 | } |
| 970 | } |
| 971 | else |
| 972 | blockCount++; |
| 973 | if (deferredCallEntry->mDoNullCheck) |
| 974 | nullCheckMethodSet.Add(deferredCallEntry->mModuleMethodInstance.mMethodInstance); |
| 975 | deferredCallEntry = deferredCallEntry->mNext; |
| 976 | } |
| 977 | |
| 978 | bool moveBlocks = mCurMethodState->mCurScope != mCurMethodState->mTailScope; |
| 979 | |
| 980 | auto valueScopeStart = ValueScopeStart(); |
| 981 | if (valueScopeStart) |
| 982 | mBfIRBuilder->SetName(valueScopeStart, "deferredScopeVal"); |
| 983 | |
| 984 | BfIRBlock condBB = mBfIRBuilder->CreateBlock("deferCall.cond", true); |
| 985 | if (moveBlocks) |
| 986 | mCurMethodState->mCurScope->mAtEndBlocks.push_back(condBB); |
nothing calls this directly
no test coverage detected