| 19779 | } |
| 19780 | |
| 19781 | void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance markFromGCThreadMethodInstance) |
| 19782 | { |
| 19783 | auto fieldType = markVal.mType; |
| 19784 | auto fieldTypeInst = fieldType->ToTypeInstance(); |
| 19785 | if (fieldType == NULL) |
| 19786 | return; |
| 19787 | |
| 19788 | if (!markVal.mType->IsComposite()) |
| 19789 | markVal = LoadValue(markVal); |
| 19790 | |
| 19791 | BfExprEvaluator exprEvaluator(this); |
| 19792 | PopulateType(markVal.mType, BfPopulateType_Data); |
| 19793 | if (markVal.mType->IsObjectOrInterface()) |
| 19794 | { |
| 19795 | BfIRValue val = markVal.mValue; |
| 19796 | val = mBfIRBuilder->CreateBitCast(val, mBfIRBuilder->MapType(mContext->mBfObjectType)); |
| 19797 | SizedArray<BfIRValue, 1> args; |
| 19798 | args.push_back(val); |
| 19799 | exprEvaluator.CreateCall(NULL, markFromGCThreadMethodInstance.mMethodInstance, markFromGCThreadMethodInstance.mFunc, false, args); |
| 19800 | } |
| 19801 | else if (fieldType->IsSizedArray()) |
| 19802 | { |
| 19803 | BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)fieldType; |
| 19804 | if (sizedArrayType->mElementType->WantsGCMarking()) |
| 19805 | { |
| 19806 | BfTypedValue arrayValue = markVal; |
| 19807 | auto intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); |
| 19808 | auto itr = CreateAlloca(intPtrType); |
| 19809 | mBfIRBuilder->CreateStore(GetDefaultValue(intPtrType), itr); |
| 19810 | |
| 19811 | auto loopBB = mBfIRBuilder->CreateBlock("loop", true); |
| 19812 | auto bodyBB = mBfIRBuilder->CreateBlock("body", true); |
| 19813 | auto doneBB = mBfIRBuilder->CreateBlock("done", true); |
| 19814 | mBfIRBuilder->CreateBr(loopBB); |
| 19815 | |
| 19816 | mBfIRBuilder->SetInsertPoint(loopBB); |
| 19817 | auto loadedItr = mBfIRBuilder->CreateLoad(itr); |
| 19818 | auto cmpRes = mBfIRBuilder->CreateCmpGTE(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), true); |
| 19819 | mBfIRBuilder->CreateCondBr(cmpRes, doneBB, bodyBB); |
| 19820 | |
| 19821 | mBfIRBuilder->SetInsertPoint(bodyBB); |
| 19822 | |
| 19823 | auto ptrType = CreatePointerType(sizedArrayType->mElementType); |
| 19824 | auto ptrValue = mBfIRBuilder->CreateBitCast(arrayValue.mValue, mBfIRBuilder->MapType(ptrType)); |
| 19825 | auto gepResult = mBfIRBuilder->CreateInBoundsGEP(ptrValue, loadedItr); |
| 19826 | auto value = BfTypedValue(gepResult, sizedArrayType->mElementType, BfTypedValueKind_Addr); |
| 19827 | |
| 19828 | EmitGCMarkValue(value, markFromGCThreadMethodInstance); |
| 19829 | |
| 19830 | auto incValue = mBfIRBuilder->CreateAdd(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1)); |
| 19831 | mBfIRBuilder->CreateStore(incValue, itr); |
| 19832 | mBfIRBuilder->CreateBr(loopBB); |
| 19833 | |
| 19834 | mBfIRBuilder->SetInsertPoint(doneBB); |
| 19835 | } |
| 19836 | } |
| 19837 | else if ((fieldType->IsComposite()) && (!fieldType->IsTypedPrimitive()) && (fieldTypeInst != NULL)) |
| 19838 | { |
nothing calls this directly
no test coverage detected