BfContext.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. #pragma once
  2. #include "BfModule.h"
  3. #include "BeefySysLib/util/Deque.h"
  4. NS_BF_BEGIN
  5. class BfWorkListEntry
  6. {
  7. public:
  8. BfType* mType;
  9. BfModule* mFromModule;
  10. int mRevision;
  11. int mSignatureRevision;
  12. int mFromModuleRevision;
  13. int mFromModuleRebuildIdx;
  14. int mReqId;
  15. static int sCurReqId;
  16. public:
  17. BfWorkListEntry()
  18. {
  19. mType = NULL;
  20. mFromModule = NULL;
  21. mRevision = -1;
  22. mSignatureRevision = -1;
  23. mFromModuleRevision = -1;
  24. mFromModuleRebuildIdx = -1;
  25. mReqId = ++sCurReqId;
  26. }
  27. };
  28. class BfTypeProcessRequest : public BfWorkListEntry
  29. {
  30. public:
  31. bool mRebuildType;
  32. BfTypeProcessRequest()
  33. {
  34. mRebuildType = false;
  35. }
  36. };
  37. class BfMethodSpecializationRequest : public BfWorkListEntry
  38. {
  39. public:
  40. int32 mMethodIdx;
  41. BfTypeVector mMethodGenericArguments;
  42. BfGetMethodInstanceFlags mFlags;
  43. BfTypeInstance* mForeignType;
  44. public:
  45. BfMethodSpecializationRequest()
  46. {
  47. mMethodIdx = -1;
  48. mFlags = BfGetMethodInstanceFlag_None;
  49. mForeignType = NULL;
  50. }
  51. void Init(BfTypeInstance* typeInstance, BfTypeInstance* foreignType, BfMethodDef* methodDef)
  52. {
  53. mType = typeInstance;
  54. mMethodIdx = methodDef->mIdx;
  55. mForeignType = foreignType;
  56. if (foreignType != NULL)
  57. BF_ASSERT(foreignType->mTypeDef->mMethods[mMethodIdx] == methodDef);
  58. else
  59. BF_ASSERT(typeInstance->mTypeDef->mMethods[mMethodIdx] == methodDef);
  60. }
  61. };
  62. class BfMethodProcessRequest : public BfWorkListEntry
  63. {
  64. public:
  65. BfMethodInstance* mMethodInstance;
  66. BfMethodProcessRequest()
  67. {
  68. mMethodInstance = NULL;
  69. }
  70. ~BfMethodProcessRequest()
  71. {
  72. Disable();
  73. }
  74. void Disable()
  75. {
  76. if (mMethodInstance != NULL)
  77. {
  78. BF_ASSERT(mMethodInstance->mMethodProcessRequest == this);
  79. mMethodInstance->mMethodProcessRequest = NULL;
  80. mMethodInstance = NULL;
  81. }
  82. }
  83. };
  84. class BfInlineMethodRequest : public BfMethodProcessRequest
  85. {
  86. public:
  87. BfIRFunction mFunc;
  88. ~BfInlineMethodRequest()
  89. {
  90. mMethodInstance = NULL;
  91. }
  92. };
  93. class BfTypeRefVerifyRequest : public BfWorkListEntry
  94. {
  95. public:
  96. BfTypeInstance* mCurTypeInstance;
  97. BfAstNode* mRefNode;
  98. };
  99. class BfMidCompileRequest : public BfWorkListEntry
  100. {
  101. public:
  102. String mReason;
  103. };
  104. struct BfStringPoolEntry
  105. {
  106. String mString;
  107. int mLastUsedRevision;
  108. int mFirstUsedRevision;
  109. };
  110. class BfGlobalContainerEntry
  111. {
  112. public:
  113. BfTypeDef* mTypeDef;
  114. BfTypeInstance* mTypeInst;
  115. };
  116. class BfTypeState
  117. {
  118. public:
  119. enum ResolveKind
  120. {
  121. ResolveKind_None,
  122. ResolveKind_BuildingGenericParams,
  123. ResolveKind_ResolvingVarType,
  124. ResolveKind_UnionInnerType,
  125. ResolveKind_LocalVariable,
  126. ResolveKind_Attributes,
  127. ResolveKind_FieldType,
  128. ResolveKind_ConstField
  129. };
  130. public:
  131. BfTypeState* mPrevState;
  132. BfType* mType;
  133. BfTypeDef* mGlobalContainerCurUserTypeDef;
  134. Array<BfGlobalContainerEntry> mGlobalContainers; // All global containers that are visible
  135. BfPopulateType mPopulateType;
  136. BfTypeReference* mCurBaseTypeRef;
  137. BfTypeInstance* mCurBaseType;
  138. BfTypeReference* mCurAttributeTypeRef;
  139. BfFieldDef* mCurFieldDef;
  140. BfMethodDef* mCurMethodDef;
  141. BfTypeDef* mCurTypeDef;
  142. BfTypeDef* mForceActiveTypeDef;
  143. BfProject* mActiveProject;
  144. ResolveKind mResolveKind;
  145. BfAstNode* mCurVarInitializer;
  146. int mArrayInitializerSize;
  147. BfTypeInstance* mInitializerBaseType;
  148. public:
  149. BfTypeState()
  150. {
  151. mPrevState = NULL;
  152. mType = NULL;
  153. mGlobalContainerCurUserTypeDef = NULL;
  154. mPopulateType = BfPopulateType_Identity;
  155. mCurBaseTypeRef = NULL;
  156. mCurBaseType = NULL;
  157. mCurFieldDef = NULL;
  158. mCurMethodDef = NULL;
  159. mCurAttributeTypeRef = NULL;
  160. mCurTypeDef = NULL;
  161. mForceActiveTypeDef = NULL;
  162. mActiveProject = NULL;
  163. mCurVarInitializer = NULL;
  164. mArrayInitializerSize = -1;
  165. mResolveKind = ResolveKind_None;
  166. mInitializerBaseType = NULL;
  167. }
  168. BfTypeState(BfType* type, BfTypeState* prevState = NULL)
  169. {
  170. mPrevState = prevState;
  171. mType = type;
  172. mGlobalContainerCurUserTypeDef = NULL;
  173. mPopulateType = BfPopulateType_Declaration;
  174. mCurBaseTypeRef = NULL;
  175. mCurBaseType = NULL;
  176. mCurFieldDef = NULL;
  177. mCurMethodDef = NULL;
  178. mCurAttributeTypeRef = NULL;
  179. mCurTypeDef = NULL;
  180. mForceActiveTypeDef = NULL;
  181. mActiveProject = NULL;
  182. mCurVarInitializer = NULL;
  183. mArrayInitializerSize = -1;
  184. mResolveKind = ResolveKind_None;
  185. mInitializerBaseType = NULL;
  186. }
  187. };
  188. class BfSavedTypeData
  189. {
  190. public:
  191. BfHotTypeData* mHotTypeData;
  192. int mTypeId;
  193. public:
  194. ~BfSavedTypeData()
  195. {
  196. delete mHotTypeData;
  197. }
  198. };
  199. struct SpecializedErrorData
  200. {
  201. // We need to store errors during type specialization and method specialization,
  202. // because if the type is deleted we need to clear the errors
  203. BfTypeInstance* mRefType;
  204. BfModule* mModule;
  205. BfMethodInstance* mMethodInstance;
  206. BfError* mError;
  207. SpecializedErrorData()
  208. {
  209. mRefType = NULL;
  210. mModule = NULL;
  211. mMethodInstance = NULL;
  212. mError = NULL;
  213. }
  214. };
  215. struct BfCaseInsensitiveStringHash
  216. {
  217. size_t operator()(const StringImpl& str) const
  218. {
  219. int curHash = 0;
  220. for (int i = 0; i < (int)str.length(); i++)
  221. curHash = ((curHash ^ (int)(intptr)toupper(str[i])) << 5) - curHash;
  222. return curHash;
  223. }
  224. };
  225. struct BfCaseInsensitiveStringEquals
  226. {
  227. bool operator()(const StringImpl& lhs, const StringImpl& rhs) const
  228. {
  229. if (lhs.length() != rhs.length())
  230. return false;
  231. return _stricmp(lhs.c_str(), rhs.c_str()) == 0;
  232. }
  233. };
  234. template <typename T>
  235. class WorkQueue : public Deque<T*>
  236. {
  237. public:
  238. BumpAllocator mWorkAlloc;
  239. int RemoveAt(int idx)
  240. {
  241. if (idx == 0)
  242. {
  243. T*& ref = (*this)[idx];
  244. if (ref != NULL)
  245. (*ref).~T();
  246. Deque<T*>::RemoveAt(0);
  247. if (this->mSize == 0)
  248. {
  249. mWorkAlloc.Clear();
  250. this->mOffset = 0;
  251. }
  252. return idx - 1;
  253. }
  254. else
  255. {
  256. T*& ref = (*this)[idx];
  257. if (ref != NULL)
  258. {
  259. (*ref).~T();
  260. ref = NULL;
  261. }
  262. return idx;
  263. }
  264. }
  265. void Clear()
  266. {
  267. Deque<T*>::Clear();
  268. mWorkAlloc.Clear();
  269. }
  270. T* Alloc()
  271. {
  272. T* item = mWorkAlloc.Alloc<T>();
  273. this->Add(item);
  274. return item;
  275. }
  276. };
  277. template <typename T>
  278. class PtrWorkQueue : public Deque<T>
  279. {
  280. public:
  281. int RemoveAt(int idx)
  282. {
  283. if (idx == 0)
  284. {
  285. Deque<T>::RemoveAt(0);
  286. return idx - 1;
  287. }
  288. else
  289. {
  290. (*this)[idx] = NULL;
  291. return idx;
  292. }
  293. }
  294. };
  295. class BfConstraintState
  296. {
  297. public:
  298. BfGenericParamInstance* mGenericParamInstance;
  299. BfType* mLeftType;
  300. BfType* mRightType;
  301. BfConstraintState* mPrevState;
  302. BfMethodInstance* mMethodInstance;
  303. BfTypeVector* mMethodGenericArgsOverride;
  304. public:
  305. BfConstraintState()
  306. {
  307. mGenericParamInstance = NULL;
  308. mLeftType = NULL;
  309. mRightType = NULL;
  310. mMethodInstance = NULL;
  311. mMethodGenericArgsOverride = NULL;
  312. mPrevState = NULL;
  313. }
  314. bool operator==(const BfConstraintState& other) const
  315. {
  316. return
  317. (mGenericParamInstance == other.mGenericParamInstance) &&
  318. (mLeftType == other.mLeftType) &&
  319. (mRightType == other.mRightType);
  320. }
  321. };
  322. enum BfFailKind
  323. {
  324. BfFailKind_Normal,
  325. BfFailKind_Deep
  326. };
  327. class BfContext
  328. {
  329. public:
  330. CritSect mCritSect;
  331. bool mDeleting;
  332. BfTypeState* mCurTypeState;
  333. BfSizedArray<BfNamespaceDeclaration*>* mCurNamespaceNodes;
  334. BfConstraintState* mCurConstraintState;
  335. bool mResolvingVarField;
  336. int mMappedObjectRevision;
  337. bool mAssertOnPopulateType;
  338. BfSystem* mSystem;
  339. BfCompiler* mCompiler;
  340. bool mAllowLockYield;
  341. bool mLockModules;
  342. BfModule* mScratchModule;
  343. BfModule* mUnreifiedModule;
  344. HashSet<String> mUsedModuleNames;
  345. HashSet<BfType*> mGhostDependencies; // We couldn't properly rebuild our dependencies
  346. Dictionary<BfProject*, BfModule*> mProjectModule;
  347. Array<BfModule*> mModules;
  348. Array<BfModule*> mDeletingModules;
  349. Dictionary<BfTypeInstance*, BfFailKind> mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile
  350. HashSet<BfTypeInstance*> mReferencedIFaceSlots;
  351. BfMethodInstance* mValueTypeDeinitSentinel;
  352. Array<BfAstNode*> mTempNodes;
  353. BfResolvedTypeSet mResolvedTypes;
  354. Array<BfType*> mTypes; // Can contain NULLs for deleted types
  355. Array<BfFieldInstance*> mFieldResolveReentrys; // For detecting 'var' field circular refs
  356. Dictionary<String, BfSavedTypeData*> mSavedTypeDataMap;
  357. Array<BfSavedTypeData*> mSavedTypeData;
  358. BfTypeInstance* mBfTypeType;
  359. BfTypeInstance* mBfObjectType;
  360. bool mCanSkipObjectCtor;
  361. bool mCanSkipValueTypeCtor;
  362. BfPointerType* mBfClassVDataPtrType;
  363. PtrWorkQueue<BfModule*> mReifyModuleWorkList;
  364. WorkQueue<BfMethodProcessRequest> mMethodWorkList;
  365. WorkQueue<BfInlineMethodRequest> mInlineMethodWorkList;
  366. WorkQueue<BfTypeProcessRequest> mPopulateTypeWorkList;
  367. WorkQueue<BfMethodSpecializationRequest> mMethodSpecializationWorkList;
  368. WorkQueue<BfTypeRefVerifyRequest> mTypeRefVerifyWorkList;
  369. WorkQueue<BfMidCompileRequest> mMidCompileWorkList;
  370. PtrWorkQueue<BfModule*> mFinishedSlotAwaitModuleWorkList;
  371. PtrWorkQueue<BfModule*> mFinishedModuleWorkList;
  372. bool mHasReifiedQueuedRebuildTypes;
  373. Array<BfGenericParamType*> mGenericParamTypes[3];
  374. Array<BfType*> mTypeGraveyard;
  375. Array<BfTypeDef*> mTypeDefGraveyard;
  376. Array<BfLocalMethod*> mLocalMethodGraveyard;
  377. Dictionary<String, int> mStringObjectPool;
  378. Dictionary<int, BfStringPoolEntry> mStringObjectIdMap;
  379. int mCurStringObjectPoolId;
  380. HashSet<BfTypeInstance*> mQueuedSpecializedMethodRebuildTypes;
  381. BfAllocPool<BfPointerType> mPointerTypePool;
  382. BfAllocPool<BfArrayType> mArrayTypePool;
  383. BfAllocPool<BfSizedArrayType> mSizedArrayTypePool;
  384. BfAllocPool<BfUnknownSizedArrayType> mUnknownSizedArrayTypePool;
  385. BfAllocPool<BfBoxedType> mBoxedTypePool;
  386. BfAllocPool<BfTupleType> mTupleTypePool;
  387. BfAllocPool<BfTypeAliasType> mAliasTypePool;
  388. BfAllocPool<BfRefType> mRefTypePool;
  389. BfAllocPool<BfModifiedTypeType> mModifiedTypeTypePool;
  390. BfAllocPool<BfTypeInstance> mGenericTypeInstancePool;
  391. BfAllocPool<BfArrayType> mArrayTypeInstancePool;
  392. BfAllocPool<BfGenericParamType> mGenericParamTypePool;
  393. BfAllocPool<BfDirectTypeDefReference> mTypeDefTypeRefPool;
  394. BfAllocPool<BfConcreteInterfaceType> mConcreteInterfaceTypePool;
  395. BfAllocPool<BfConstExprValueType> mConstExprValueTypePool;
  396. BfAllocPool<BfDelegateType> mDelegateTypePool;
  397. BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length];
  398. BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length];
  399. public:
  400. void AssignModule(BfType* type);
  401. void HandleTypeWorkItem(BfType* type);
  402. void EnsureHotMangledVirtualMethodName(BfMethodInstance* methodInstance);
  403. void EnsureHotMangledVirtualMethodNames();
  404. void PopulateHotTypeDataVTable(BfTypeInstance* typeInstance);
  405. void DeleteType(BfType* type, bool deferDepRebuilds = false);
  406. void UpdateAfterDeletingTypes();
  407. void VerifyTypeLookups(BfTypeInstance* typeInst);
  408. void GenerateModuleName_TypeInst(BfTypeInstance* typeInst, StringImpl& name);
  409. void GenerateModuleName_Type(BfType* type, StringImpl& name);
  410. void GenerateModuleName(BfTypeInstance* typeInst, StringImpl& name);
  411. bool IsSentinelMethod(BfMethodInstance* methodInstance);
  412. void SaveDeletingType(BfType* type);
  413. BfType* FindType(const StringImpl& typeName);
  414. String TypeIdToString(int typeId);
  415. BfHotTypeData* GetHotTypeData(int typeId);
  416. void ReflectInit();
  417. public:
  418. BfContext(BfCompiler* compiler);
  419. ~BfContext();
  420. void ReportMemory(MemReporter* memReporter);
  421. void ProcessMethod(BfMethodInstance* methodInstance);
  422. int GetStringLiteralId(const StringImpl& str);
  423. void CheckLockYield();
  424. bool IsCancellingAndYield();
  425. void QueueFinishModule(BfModule * module);
  426. void CancelWorkItems();
  427. bool ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods);
  428. void HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTempType = false);
  429. void PreUpdateRevisedTypes();
  430. void UpdateRevisedTypes();
  431. void VerifyTypeLookups();
  432. void QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkSpecializedMethodRebuildFlag);
  433. void MarkAsReferenced(BfDependedType* depType);
  434. void RemoveInvalidFailTypes();
  435. bool IsWorkItemValid(BfWorkListEntry* item);
  436. bool IsWorkItemValid(BfMethodInstance* methodInstance);
  437. bool IsWorkItemValid(BfMethodProcessRequest* item);
  438. bool IsWorkItemValid(BfInlineMethodRequest* item);
  439. bool IsWorkItemValid(BfMethodSpecializationRequest* item);
  440. void RemoveInvalidWorkItems();
  441. BfType* FindTypeById(int typeId);
  442. void AddTypeToWorkList(BfType* type);
  443. void ValidateDependencies();
  444. void RebuildType(BfType* type, bool deleteOnDemandTypes = true, bool rebuildModule = true, bool placeSpecializiedInPurgatory = true);
  445. void RebuildDependentTypes(BfDependedType* dType);
  446. void QueueMidCompileRebuildDependentTypes(BfDependedType* dType, const String& reason);
  447. void RebuildDependentTypes_MidCompile(BfDependedType* dType, const String& reason);
  448. bool IsRebuilding(BfType* type);
  449. bool CanRebuild(BfType* type);
  450. void TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange);
  451. void TypeMethodSignaturesChanged(BfTypeInstance* typeInst);
  452. void TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst);
  453. void TypeConstEvalChanged(BfTypeInstance* typeInst);
  454. void TypeConstEvalFieldChanged(BfTypeInstance* typeInst);
  455. void CheckSpecializedErrorData();
  456. void TryUnreifyModules();
  457. void MarkUsedModules(BfProject* project, BfModule* module);
  458. void RemapObject();
  459. void Finish();
  460. void Cleanup();
  461. };
  462. NS_BF_END