Ver código fonte

Removed bogus mVDataHotIdx check, now using balanced hot chain breaking

Brian Fiete 6 meses atrás
pai
commit
d9eca5ba5c
3 arquivos alterados com 32 adições e 10 exclusões
  1. 30 10
      IDEHelper/DbgModule.cpp
  2. 1 0
      IDEHelper/DebugTarget.cpp
  3. 1 0
      IDEHelper/DebugTarget.h

+ 30 - 10
IDEHelper/DbgModule.cpp

@@ -5395,21 +5395,41 @@ void DbgModule::HotReplaceMethods(DbgType* newType, DbgType* primaryType)
 
 
 	MultiDictionary<StringView, DbgSubprogram*> oldProgramMap;
 	MultiDictionary<StringView, DbgSubprogram*> oldProgramMap;
 	auto _AddToHotReplacedMethodList = [&](DbgSubprogram* oldMethod)
 	auto _AddToHotReplacedMethodList = [&](DbgSubprogram* oldMethod)
-		{	
-			int hotIdx = oldMethod->mCompileUnit->mDbgModule->mHotIdx;
-			if ((hotIdx > 0) && (hotIdx < mDebugTarget->mVDataHotIdx))
-			{
-				// Too old
-				return;
-			}
-
+		{
 			oldMethod->PopulateSubprogram();
 			oldMethod->PopulateSubprogram();
 			if (oldMethod->mBlock.IsEmpty())
 			if (oldMethod->mBlock.IsEmpty())
-				return;			
+				return;
 			auto symInfo = mDebugTarget->mSymbolMap.Get(oldMethod->mBlock.mLowPC);
 			auto symInfo = mDebugTarget->mSymbolMap.Get(oldMethod->mBlock.mLowPC);
 			if (symInfo != NULL)
 			if (symInfo != NULL)
 			{
 			{
-				oldProgramMap.Add(StringView(symInfo->mName), oldMethod);
+				StringView key = StringView(symInfo->mName);
+				DbgSubprogram** oldestValuePtr = NULL;
+				int count = 0;
+				for (auto itr = oldProgramMap.TryGet(key); itr != oldProgramMap.end(); ++itr)
+				{
+					auto& checkProgram = itr.GetValue();
+					if ((oldestValuePtr == NULL) ||
+						(checkProgram->mCompileUnit->mDbgModule->mHotIdx < (*oldestValuePtr)->mCompileUnit->mDbgModule->mHotIdx))
+						oldestValuePtr = &checkProgram;					
+					count++;
+				}
+
+				// If we hot jump from only the last version of the method then we potentially create a long "jump chain"
+				//  from a call to the original method through every hot version to this current one. We also don't want to 
+				//  blindly update every old version because that will cause hot loading to become too slow over many iterations. 
+				//  We balance this by linking SOME old versions to the newest one, decreasing in frequency as we move through 
+				//  the older methods
+				if ((count == 0) ||
+					(mDebugTarget->mHotChainBreakIdx++) % (1 << (count + 1)) == 0)
+				{
+					oldProgramMap.Add(StringView(symInfo->mName), oldMethod);
+				}
+				else if ((count > 1) && ((mDebugTarget->mHotChainBreakIdx++) % 2 == 0))
+				{
+					// Prefer the older of the methods when we are not adding a new entry. This will also ensure that the 
+					//  original method gets updated very often
+					*oldestValuePtr = oldMethod;
+				}
 			}
 			}
 		};
 		};
 
 

+ 1 - 0
IDEHelper/DebugTarget.cpp

@@ -34,6 +34,7 @@ DebugTarget::DebugTarget(WinDebugger* debugger)
 	mHotHeapReserveSize = 0;
 	mHotHeapReserveSize = 0;
 	mLastHotHeapCleanIdx = 0;
 	mLastHotHeapCleanIdx = 0;
 	mVDataHotIdx = -1;
 	mVDataHotIdx = -1;
+	mHotChainBreakIdx = 0;
 	mIsEmpty = false;
 	mIsEmpty = false;
 	mWasLocallyBuilt = false;
 	mWasLocallyBuilt = false;
 	mCurModuleId = 0;
 	mCurModuleId = 0;

+ 1 - 0
IDEHelper/DebugTarget.h

@@ -50,6 +50,7 @@ public:
 	int64 mHotHeapReserveSize;
 	int64 mHotHeapReserveSize;
 	int mLastHotHeapCleanIdx;
 	int mLastHotHeapCleanIdx;
 	int mVDataHotIdx;
 	int mVDataHotIdx;
+	int mHotChainBreakIdx;
 	String mTargetPath;
 	String mTargetPath;
 	DbgModule* mLaunchBinary;
 	DbgModule* mLaunchBinary;
 	DbgModule* mTargetBinary;
 	DbgModule* mTargetBinary;