diff --git a/lib/Runtime/Types/PathTypeHandler.cpp b/lib/Runtime/Types/PathTypeHandler.cpp index c704a9e8e59..63620e7eefc 100644 --- a/lib/Runtime/Types/PathTypeHandler.cpp +++ b/lib/Runtime/Types/PathTypeHandler.cpp @@ -1552,6 +1552,16 @@ namespace Js Assert(cachedDynamicTypeHandler->GetInlineSlotCapacity() >= roundedInlineSlotCapacity); Assert(cachedDynamicTypeHandler->GetInlineSlotCapacity() >= GetPropertyCount()); cachedDynamicTypeHandler->ShrinkSlotAndInlineSlotCapacity(); + + // If slot capacity doesn't match after shrinking, it could be because oldType was shrunk and + // newType evolved. In that case, we should update the cache with new type + if (cachedDynamicTypeHandler->GetInlineSlotCapacity() != roundedInlineSlotCapacity) + { + cachedDynamicType = nullptr; +#if DBG + swprintf_s(reason, 1024, _u("InlineSlotCapacity mismatch after shrinking. Required = %d, Cached = %d"), roundedInlineSlotCapacity, cachedDynamicTypeHandler->GetInlineSlotCapacity()); +#endif + } } } } diff --git a/test/Prototypes/ChangePrototype.baseline b/test/Prototypes/ChangePrototype.baseline index 3d992a12c0e..41b7a933802 100644 --- a/test/Prototypes/ChangePrototype.baseline +++ b/test/Prototypes/ChangePrototype.baseline @@ -26,3 +26,6 @@ Changing __proto__ TypeSharing: Updating prototype object's DictionarySlot cache in __proto__. Changing __proto__ TypeSharing: Reusing prototype object's DictionarySlot cache in __proto__. +TypeSharing: Updating prototype object's InlineSlot cache in CreateObject. +TypeSharing: Updating prototype object's DictionarySlot cache in __proto__. +TypeSharing: Updating prototype object's DictionarySlot cache in __proto__. diff --git a/test/Prototypes/ChangePrototype.js b/test/Prototypes/ChangePrototype.js index 3e47c8bd907..677b4d77927 100644 --- a/test/Prototypes/ChangePrototype.js +++ b/test/Prototypes/ChangePrototype.js @@ -80,5 +80,27 @@ function test2() { y.__proto__ = obj; // cached T2's inlineSlotCapacity doesn't match y's T1 } +function test3() { + // no switches needed + var proto = {}; + + function foo() { + } + + var x = new foo(); + var y = new foo(); + y.__proto__ = proto; // empty type cached in map of proto object + y._a = 1; // evolve cached type created above + y._b = 1; + y._c = 1; + y._d = 1; + var z = new foo(); // this shrunk oldType's slotCapacity from 8 to 2. + + // retrived the cached type which was evolved. + // Realized that oldType's slotCapacity has shrunk, we shrink slot capacity of cachedType but it doesn't match because cachedType has evolved + z.__proto__ = proto; +} + test1(); -test2(); \ No newline at end of file +test2(); +test3(); \ No newline at end of file