Skip to content

Commit 17a8a8b

Browse files
Breanstorming
1 parent f2ceadd commit 17a8a8b

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

lib/Runtime/Base/ThreadContext.h

+8
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,14 @@ class ThreadContext sealed :
13841384
#endif
13851385

13861386
public:
1387+
template<class Fn>
1388+
void MapIsInstInlineCaches(Fn fn) const
1389+
{
1390+
isInstInlineCacheByFunction.Map([fn](const Js::Var function, Js::IsInstInlineCache* inlineCacheList) {
1391+
fn(function, inlineCacheList);
1392+
});
1393+
}
1394+
13871395
void InvalidateIsInstInlineCachesForFunction(Js::Var function);
13881396
void InvalidateAllIsInstInlineCaches();
13891397
bool AreAllIsInstInlineCachesInvalidated() const;

lib/Runtime/Library/JavascriptObject.cpp

+32-3
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)