@@ -145,6 +145,47 @@ void CALLBACK TraceDependentHandle(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pEx
145145 }
146146}
147147
148+ void CALLBACK UpdateWeakInteriorHandle (_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtraInfo, uintptr_t lp1, uintptr_t lp2)
149+ {
150+ LIMITED_METHOD_CONTRACT;
151+ _ASSERTE (pExtraInfo);
152+
153+ Object **pPrimaryRef = (Object **)pObjRef;
154+ uintptr_t **ppInteriorPtrRef = (uintptr_t **)pExtraInfo;
155+
156+ LOG ((LF_GC, LL_INFO10000, LOG_HANDLE_OBJECT (" Querying for new location of " ,
157+ pPrimaryRef, " to " , *pPrimaryRef)));
158+
159+ Object *pOldPrimary = *pPrimaryRef;
160+
161+ _ASSERTE (lp2);
162+ promote_func* callback = (promote_func*) lp2;
163+ callback (pPrimaryRef, (ScanContext *)lp1, 0 );
164+
165+ Object *pNewPrimary = *pPrimaryRef;
166+ if (pNewPrimary != NULL )
167+ {
168+ uintptr_t pOldInterior = **ppInteriorPtrRef;
169+ uintptr_t delta = ((uintptr_t )pNewPrimary) - ((uintptr_t )pOldPrimary);
170+ uintptr_t pNewInterior = pOldInterior + delta;
171+ **ppInteriorPtrRef = pNewInterior;
172+ #ifdef _DEBUG
173+ if (pOldPrimary != *pPrimaryRef)
174+ LOG ((LF_GC, LL_INFO10000, " Updating " FMT_HANDLE " from" FMT_ADDR " to " FMT_OBJECT " \n " ,
175+ DBG_ADDR (pPrimaryRef), DBG_ADDR (pOldPrimary), DBG_ADDR (*pPrimaryRef)));
176+ else
177+ LOG ((LF_GC, LL_INFO10000, " Updating " FMT_HANDLE " - " FMT_OBJECT " did not move\n " ,
178+ DBG_ADDR (pPrimaryRef), DBG_ADDR (*pPrimaryRef)));
179+ if (pOldInterior != pNewInterior)
180+ LOG ((LF_GC, LL_INFO10000, " Updating " FMT_HANDLE " from" FMT_ADDR " to " FMT_OBJECT " \n " ,
181+ DBG_ADDR (*ppInteriorPtrRef), DBG_ADDR (pOldInterior), DBG_ADDR (pNewInterior)));
182+ else
183+ LOG ((LF_GC, LL_INFO10000, " Updating " FMT_HANDLE " - " FMT_OBJECT " did not move\n " ,
184+ DBG_ADDR (*ppInteriorPtrRef), DBG_ADDR (pOldInterior)));
185+ #endif
186+ }
187+ }
188+
148189void CALLBACK UpdateDependentHandle (_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtraInfo, uintptr_t lp1, uintptr_t lp2)
149190{
150191 LIMITED_METHOD_CONTRACT;
@@ -427,6 +468,7 @@ void CALLBACK ScanPointerForProfilerAndETW(_UNCHECKED_OBJECTREF *pObjRef, uintpt
427468 break ;
428469 case HNDTYPE_WEAK_SHORT:
429470 case HNDTYPE_WEAK_LONG:
471+ case HNDTYPE_WEAK_INTERIOR_POINTER:
430472#ifdef FEATURE_WEAK_NATIVE_COM_HANDLES
431473 case HNDTYPE_WEAK_NATIVE_COM:
432474#endif // FEATURE_WEAK_NATIVE_COM_HANDLES
@@ -527,6 +569,7 @@ static const uint32_t s_rgTypeFlags[] =
527569 HNDF_NORMAL, // HNDTYPE_ASYNCPINNED
528570 HNDF_EXTRAINFO, // HNDTYPE_SIZEDREF
529571 HNDF_EXTRAINFO, // HNDTYPE_WEAK_NATIVE_COM
572+ HNDF_EXTRAINFO, // HNDTYPE_WEAK_INTERIOR_POINTER
530573};
531574
532575int getNumberOfSlots ()
@@ -1170,6 +1213,7 @@ void Ref_CheckReachable(uint32_t condemned, uint32_t maxgen, ScanContext *sc)
11701213#ifdef FEATURE_REFCOUNTED_HANDLES
11711214 HNDTYPE_REFCOUNTED,
11721215#endif
1216+ HNDTYPE_WEAK_INTERIOR_POINTER
11731217 };
11741218
11751219 // check objects pointed to by short weak handles
@@ -1339,6 +1383,40 @@ void Ref_ScanDependentHandlesForClearing(uint32_t condemned, uint32_t maxgen, Sc
13391383 }
13401384}
13411385
1386+ // Perform a scan of weak interior pointers for the purpose of updating handles to track relocated objects.
1387+ void Ref_ScanWeakInteriorPointersForRelocation (uint32_t condemned, uint32_t maxgen, ScanContext* sc, Ref_promote_func* fn)
1388+ {
1389+ LOG ((LF_GC, LL_INFO10000, " Relocating moved dependent handles in generation %u\n " , condemned));
1390+ uint32_t type = HNDTYPE_WEAK_INTERIOR_POINTER;
1391+ uint32_t flags = (sc->concurrent ) ? HNDGCF_ASYNC : HNDGCF_NORMAL;
1392+ flags |= HNDGCF_EXTRAINFO;
1393+
1394+ HandleTableMap *walk = &g_HandleTableMap;
1395+ while (walk)
1396+ {
1397+ for (uint32_t i = 0 ; i < INITIAL_HANDLE_TABLE_ARRAY_SIZE; i ++)
1398+ {
1399+ if (walk->pBuckets [i] != NULL )
1400+ {
1401+ int uCPUindex = getSlotNumber (sc);
1402+ int uCPUlimit = getNumberOfSlots ();
1403+ assert (uCPUlimit > 0 );
1404+ int uCPUstep = getThreadCount (sc);
1405+ HHANDLETABLE* pTable = walk->pBuckets [i]->pTable ;
1406+ for ( ; uCPUindex < uCPUlimit; uCPUindex += uCPUstep)
1407+ {
1408+ HHANDLETABLE hTable = pTable[uCPUindex];
1409+ if (hTable)
1410+ {
1411+ HndScanHandlesForGC (hTable, UpdateWeakInteriorHandle, uintptr_t (sc), uintptr_t (fn), &type, 1 , condemned, maxgen, flags );
1412+ }
1413+ }
1414+ }
1415+ }
1416+ walk = walk->pNext ;
1417+ }
1418+ }
1419+
13421420// Perform a scan of dependent handles for the purpose of updating handles to track relocated objects.
13431421void Ref_ScanDependentHandlesForRelocation (uint32_t condemned, uint32_t maxgen, ScanContext* sc, Ref_promote_func* fn)
13441422{
@@ -1590,6 +1668,7 @@ void Ref_ScanHandlesForProfilerAndETW(uint32_t maxgen, uintptr_t lp1, handle_sca
15901668 HNDTYPE_ASYNCPINNED,
15911669#endif
15921670 HNDTYPE_SIZEDREF,
1671+ HNDTYPE_WEAK_INTERIOR_POINTER
15931672 };
15941673
15951674 uint32_t flags = HNDGCF_NORMAL;
@@ -1712,6 +1791,7 @@ void Ref_AgeHandles(uint32_t condemned, uint32_t maxgen, ScanContext* sc)
17121791 HNDTYPE_ASYNCPINNED,
17131792#endif
17141793 HNDTYPE_SIZEDREF,
1794+ HNDTYPE_WEAK_INTERIOR_POINTER
17151795 };
17161796
17171797 // perform a multi-type scan that ages the handles
@@ -1766,6 +1846,7 @@ void Ref_RejuvenateHandles(uint32_t condemned, uint32_t maxgen, ScanContext* sc)
17661846 HNDTYPE_ASYNCPINNED,
17671847#endif
17681848 HNDTYPE_SIZEDREF,
1849+ HNDTYPE_WEAK_INTERIOR_POINTER
17691850 };
17701851
17711852 // reset the ages of these handles
@@ -1819,6 +1900,7 @@ void Ref_VerifyHandleTable(uint32_t condemned, uint32_t maxgen, ScanContext* sc)
18191900#endif
18201901 HNDTYPE_SIZEDREF,
18211902 HNDTYPE_DEPENDENT,
1903+ HNDTYPE_WEAK_INTERIOR_POINTER
18221904 };
18231905
18241906 // verify these handles
0 commit comments