@@ -245,11 +245,40 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec
245245 isInvalidationOfInlineCacheNeeded = false ;
246246 }
247247
248- // Invalidate the "instanceof" cache
249- scriptContext->GetThreadContext ()->InvalidateAllIsInstInlineCaches ();
250-
251248 if (isInvalidationOfInlineCacheNeeded)
252249 {
250+ // Invalidate the "instanceof" cache
251+ ThreadContext* threadContext = scriptContext->GetThreadContext ();
252+ threadContext->MapIsInstInlineCaches ([threadContext, object](const Js::Var function, Js::IsInstInlineCache* inlineCacheList) {
253+ Assert (inlineCacheList != nullptr );
254+
255+ // ToDo: Check for changed "function"
256+
257+ Js::IsInstInlineCache* curInlineCache;
258+ Js::IsInstInlineCache* nextInlineCache;
259+ for (curInlineCache = inlineCacheList; curInlineCache != nullptr ; curInlineCache = nextInlineCache)
260+ {
261+ // Stash away the next cache before we potentially zero out current one
262+ nextInlineCache = curInlineCache->next ;
263+
264+ bool clearCurrentCache = false ;
265+ JavascriptOperators::MapObjectAndPrototypes<true >(curInlineCache->type ->GetPrototype (), [&](RecyclableObject* obj)
266+ {
267+ if (object->GetType () == obj->GetType ())
268+ clearCurrentCache = true ;
269+ });
270+
271+ if (clearCurrentCache)
272+ {
273+ // Fix cache list
274+ // Deletes empty entries
275+ threadContext->UnregisterIsInstInlineCache (curInlineCache, function);
276+ // Actually invalidate current cache
277+ memset (curInlineCache, 0 , sizeof (Js::IsInstInlineCache));
278+ }
279+ }
280+ });
281+
253282 bool allProtoCachesInvalidated = false ;
254283
255284 JavascriptOperators::MapObjectAndPrototypes<true >(newPrototype, [&](RecyclableObject* obj)
0 commit comments