@@ -9014,20 +9014,34 @@ void Recycler::SetObjectBeforeCollectCallback(void* object,
9014
9014
return ; // NOP at shutdown
9015
9015
}
9016
9016
9017
- if (objectBeforeCollectCallbackList == nullptr )
9017
+ if (this -> objectBeforeCollectCallbackList == nullptr )
9018
9018
{
9019
9019
if (callback == nullptr ) return ;
9020
- objectBeforeCollectCallbackList = Anew (&this ->objectBeforeCollectCallbackArena , ObjectBeforeCollectCallbackList, &this ->objectBeforeCollectCallbackArena );
9020
+ this -> objectBeforeCollectCallbackList = Anew (&this ->objectBeforeCollectCallbackArena , ObjectBeforeCollectCallbackList, &this ->objectBeforeCollectCallbackArena );
9021
9021
}
9022
9022
9023
- // only allow 1 callback per object
9024
- objectBeforeCollectCallbackList->Push (ObjectBeforeCollectCallbackData (object, callbackWrapper, callback, callbackState, threadContext));
9023
+ if (callback)
9024
+ {
9025
+ this ->objectBeforeCollectCallbackList ->Push (ObjectBeforeCollectCallbackData (object, callbackWrapper, callback, callbackState, threadContext));
9025
9026
9026
- if (callback != nullptr && this ->IsInObjectBeforeCollectCallback ()) // revive
9027
+ if (this ->IsInObjectBeforeCollectCallback ()) // revive
9028
+ {
9029
+ this ->ScanMemory <false >(&object, sizeof (object));
9030
+ this ->ProcessMark (/* background*/ false );
9031
+ }
9032
+ }
9033
+ else
9027
9034
{
9028
- this ->ScanMemory <false >(&object, sizeof (object));
9029
- this ->ProcessMark (/* background*/ false );
9035
+ // null callback means unregister
9036
+ FOREACH_SLIST_ENTRY_EDITING (ObjectBeforeCollectCallbackData, callbackData, this ->objectBeforeCollectCallbackList , iter)
9037
+ {
9038
+ if (callbackData.object == object)
9039
+ {
9040
+ iter.RemoveCurrent ();
9041
+ }
9042
+ } NEXT_SLIST_ENTRY_EDITING;
9030
9043
}
9044
+
9031
9045
}
9032
9046
9033
9047
void Recycler::SetDOMWrapperTracingCallback (void * state, DOMWrapperTracingCallback tracingCallback, DOMWrapperTracingDoneCallback tracingDoneCallback, DOMWrapperTracingEnterFinalPauseCallback enterFinalPauseCallback)
@@ -9111,10 +9125,19 @@ bool Recycler::ProcessObjectBeforeCollectCallbacks(bool atShutdown/*= false*/)
9111
9125
*&oldCallbackList = this ->objectBeforeCollectCallbackList ;
9112
9126
this ->objectBeforeCollectCallbackList = tmp;
9113
9127
9114
- oldCallbackList-> Map ([&]( const ObjectBeforeCollectCallbackData& data)
9128
+ try
9115
9129
{
9116
- this ->objectBeforeCollectCallbackList ->Push (data);
9117
- });
9130
+ AUTO_NESTED_HANDLED_EXCEPTION_TYPE (ExceptionType_OutOfMemory);
9131
+ oldCallbackList->Map ([&](const ObjectBeforeCollectCallbackData& data)
9132
+ {
9133
+ this ->objectBeforeCollectCallbackList ->Push (data);
9134
+ });
9135
+ }
9136
+ catch (Js::OutOfMemoryException)
9137
+ {
9138
+ // can't recover from OOM here
9139
+ AssertOrFailFast (UNREACHED);
9140
+ }
9118
9141
}
9119
9142
}
9120
9143
0 commit comments