From f2ceadde57feed9b7461da7e6feadd58997e30f1 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Mon, 17 Oct 2022 13:59:07 +0200 Subject: [PATCH 01/12] Invalidate `InstInline` cache --- lib/Runtime/Library/JavascriptObject.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Runtime/Library/JavascriptObject.cpp b/lib/Runtime/Library/JavascriptObject.cpp index b38b535db43..8eac9a6c59a 100644 --- a/lib/Runtime/Library/JavascriptObject.cpp +++ b/lib/Runtime/Library/JavascriptObject.cpp @@ -245,6 +245,9 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec isInvalidationOfInlineCacheNeeded = false; } + // Invalidate the "instanceof" cache + scriptContext->GetThreadContext()->InvalidateAllIsInstInlineCaches(); + if (isInvalidationOfInlineCacheNeeded) { bool allProtoCachesInvalidated = false; From 17a8a8b1cb4e85e581e990bc5d261df379f89e65 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 16:01:19 +0200 Subject: [PATCH 02/12] Breanstorming --- lib/Runtime/Base/ThreadContext.h | 8 ++++++ lib/Runtime/Library/JavascriptObject.cpp | 35 ++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/Runtime/Base/ThreadContext.h b/lib/Runtime/Base/ThreadContext.h index ec823a39986..6f732fb979f 100644 --- a/lib/Runtime/Base/ThreadContext.h +++ b/lib/Runtime/Base/ThreadContext.h @@ -1384,6 +1384,14 @@ class ThreadContext sealed : #endif public: + template + void MapIsInstInlineCaches(Fn fn) const + { + isInstInlineCacheByFunction.Map([fn](const Js::Var function, Js::IsInstInlineCache* inlineCacheList) { + fn(function, inlineCacheList); + }); + } + void InvalidateIsInstInlineCachesForFunction(Js::Var function); void InvalidateAllIsInstInlineCaches(); bool AreAllIsInstInlineCachesInvalidated() const; diff --git a/lib/Runtime/Library/JavascriptObject.cpp b/lib/Runtime/Library/JavascriptObject.cpp index 8eac9a6c59a..29023f83999 100644 --- a/lib/Runtime/Library/JavascriptObject.cpp +++ b/lib/Runtime/Library/JavascriptObject.cpp @@ -245,11 +245,40 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec isInvalidationOfInlineCacheNeeded = false; } - // Invalidate the "instanceof" cache - scriptContext->GetThreadContext()->InvalidateAllIsInstInlineCaches(); - if (isInvalidationOfInlineCacheNeeded) { + // Invalidate the "instanceof" cache + ThreadContext* threadContext = scriptContext->GetThreadContext(); + threadContext->MapIsInstInlineCaches([threadContext, object](const Js::Var function, Js::IsInstInlineCache* inlineCacheList) { + Assert(inlineCacheList != nullptr); + + // ToDo: Check for changed "function" + + Js::IsInstInlineCache* curInlineCache; + Js::IsInstInlineCache* nextInlineCache; + for (curInlineCache = inlineCacheList; curInlineCache != nullptr; curInlineCache = nextInlineCache) + { + // Stash away the next cache before we potentially zero out current one + nextInlineCache = curInlineCache->next; + + bool clearCurrentCache = false; + JavascriptOperators::MapObjectAndPrototypes(curInlineCache->type->GetPrototype(), [&](RecyclableObject* obj) + { + if (object->GetType() == obj->GetType()) + clearCurrentCache = true; + }); + + if (clearCurrentCache) + { + // Fix cache list + // Deletes empty entries + threadContext->UnregisterIsInstInlineCache(curInlineCache, function); + // Actually invalidate current cache + memset(curInlineCache, 0, sizeof(Js::IsInstInlineCache)); + } + } + }); + bool allProtoCachesInvalidated = false; JavascriptOperators::MapObjectAndPrototypes(newPrototype, [&](RecyclableObject* obj) From 2d7e459c40cbf12efff28e00811dc768b7d52f65 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 16:23:46 +0200 Subject: [PATCH 03/12] More checks --- lib/Runtime/Library/JavascriptObject.cpp | 34 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/Runtime/Library/JavascriptObject.cpp b/lib/Runtime/Library/JavascriptObject.cpp index 29023f83999..64bb0e9c99c 100644 --- a/lib/Runtime/Library/JavascriptObject.cpp +++ b/lib/Runtime/Library/JavascriptObject.cpp @@ -252,7 +252,24 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec threadContext->MapIsInstInlineCaches([threadContext, object](const Js::Var function, Js::IsInstInlineCache* inlineCacheList) { Assert(inlineCacheList != nullptr); - // ToDo: Check for changed "function" + JavascriptFunction* jsFunction = VarTo(function); + + // Check if cached function type is same as the old prototype + bool clearCurrentCacheList = jsFunction->GetType() == object->GetType(); + if (!clearCurrentCacheList) + { + // Check if function prototype contains old prototype + JavascriptOperators::MapObjectAndPrototypes(jsFunction->GetPrototype(), [&](RecyclableObject* obj) + { + if (object->GetType() == obj->GetType()) + clearCurrentCacheList = true; + }); + } + if (clearCurrentCacheList) + { + threadContext->InvalidateIsInstInlineCachesForFunction(function); + return; + } Js::IsInstInlineCache* curInlineCache; Js::IsInstInlineCache* nextInlineCache; @@ -261,12 +278,15 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec // Stash away the next cache before we potentially zero out current one nextInlineCache = curInlineCache->next; - bool clearCurrentCache = false; - JavascriptOperators::MapObjectAndPrototypes(curInlineCache->type->GetPrototype(), [&](RecyclableObject* obj) - { - if (object->GetType() == obj->GetType()) - clearCurrentCache = true; - }); + bool clearCurrentCache = curInlineCache->type == object->GetType(); + if (!clearCurrentCache) { + // Check if function prototype contains old prototype + JavascriptOperators::MapObjectAndPrototypes(curInlineCache->type->GetPrototype(), [&](RecyclableObject* obj) + { + if (object->GetType() == obj->GetType()) + clearCurrentCache = true; + }); + } if (clearCurrentCache) { From 641e8ca30841df529fac3fe9b87c5e024c4002d8 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 16:28:00 +0200 Subject: [PATCH 04/12] Cleanup and copyright --- lib/Runtime/Base/ThreadContext.h | 1 + lib/Runtime/Library/JavascriptObject.cpp | 21 +-------------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/lib/Runtime/Base/ThreadContext.h b/lib/Runtime/Base/ThreadContext.h index 6f732fb979f..b0b7f8df990 100644 --- a/lib/Runtime/Base/ThreadContext.h +++ b/lib/Runtime/Base/ThreadContext.h @@ -1,5 +1,6 @@ //------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. +// Copyright (c) ChakraCore Project Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #pragma once diff --git a/lib/Runtime/Library/JavascriptObject.cpp b/lib/Runtime/Library/JavascriptObject.cpp index 64bb0e9c99c..8f99e10c331 100644 --- a/lib/Runtime/Library/JavascriptObject.cpp +++ b/lib/Runtime/Library/JavascriptObject.cpp @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. -// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved. +// Copyright (c) ChakraCore Project Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #include "RuntimeLibraryPch.h" @@ -252,25 +252,6 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec threadContext->MapIsInstInlineCaches([threadContext, object](const Js::Var function, Js::IsInstInlineCache* inlineCacheList) { Assert(inlineCacheList != nullptr); - JavascriptFunction* jsFunction = VarTo(function); - - // Check if cached function type is same as the old prototype - bool clearCurrentCacheList = jsFunction->GetType() == object->GetType(); - if (!clearCurrentCacheList) - { - // Check if function prototype contains old prototype - JavascriptOperators::MapObjectAndPrototypes(jsFunction->GetPrototype(), [&](RecyclableObject* obj) - { - if (object->GetType() == obj->GetType()) - clearCurrentCacheList = true; - }); - } - if (clearCurrentCacheList) - { - threadContext->InvalidateIsInstInlineCachesForFunction(function); - return; - } - Js::IsInstInlineCache* curInlineCache; Js::IsInstInlineCache* nextInlineCache; for (curInlineCache = inlineCacheList; curInlineCache != nullptr; curInlineCache = nextInlineCache) From 11e42e3d341349c647c607be2322d324b945b5f2 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 20:27:29 +0200 Subject: [PATCH 05/12] Added test --- test/InlineCaches/isinstanceof.js | 37 +++++++++++++++++++++++++++++++ test/InlineCaches/rlexe.xml | 6 +++++ 2 files changed, 43 insertions(+) create mode 100644 test/InlineCaches/isinstanceof.js diff --git a/test/InlineCaches/isinstanceof.js b/test/InlineCaches/isinstanceof.js new file mode 100644 index 00000000000..e12854b1fd0 --- /dev/null +++ b/test/InlineCaches/isinstanceof.js @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Copyright (c) ChakraCore Project Contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +// @ts-check +/// +WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js"); + +const tests = [{ + name: "Clear IsInstInlineCache of 'Object.setPrototypeOf'", + body: function () { + // See https://github.com/chakra-core/ChakraCore/issues/5915 + + function Component() { } + function Shape() { } + + function Box() { } + Box.prototype = Object.create(Shape.prototype); + Box.prototype.constructor = Box; + + function checkInstanceOf(a, b) { + return a instanceof b; + } + + assert.isFalse(Box.prototype instanceof Component, "Box.prototype instanceof Component"); + assert.isFalse(checkInstanceOf(Box.prototype, Component), "checkInstanceOf(Box.prototype, Component)"); + + Object.setPrototypeOf(Shape.prototype, Component.prototype); + + assert.isTrue(Box.prototype instanceof Component, "Box.prototype instanceof Component"); + assert.isTrue(checkInstanceOf(Box.prototype, Component), "checkInstanceOf(Box.prototype, Component)"); + } +}]; + +testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" }); diff --git a/test/InlineCaches/rlexe.xml b/test/InlineCaches/rlexe.xml index 9a684a2f88e..3aa19809280 100644 --- a/test/InlineCaches/rlexe.xml +++ b/test/InlineCaches/rlexe.xml @@ -137,4 +137,10 @@ bug_vso_os_1206083.baseline + + + isinstanceof.js + -args summary -endargs + + From 21e41750b607f4a5714d2703fc059bb21ecef34c Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 12:20:30 -0700 Subject: [PATCH 06/12] Fix style --- test/InlineCaches/rlexe.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/InlineCaches/rlexe.xml b/test/InlineCaches/rlexe.xml index 3aa19809280..ebe56150a33 100644 --- a/test/InlineCaches/rlexe.xml +++ b/test/InlineCaches/rlexe.xml @@ -138,9 +138,9 @@ - - isinstanceof.js - -args summary -endargs - + + isinstanceof.js + -args summary -endargs + From 90c8e3009cbabae1dadc5de68f3f541dd18910cf Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 23:00:33 +0200 Subject: [PATCH 07/12] Ignore cache for primitive values --- lib/Runtime/Library/JavascriptObject.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Runtime/Library/JavascriptObject.cpp b/lib/Runtime/Library/JavascriptObject.cpp index 8f99e10c331..57a422ad7c4 100644 --- a/lib/Runtime/Library/JavascriptObject.cpp +++ b/lib/Runtime/Library/JavascriptObject.cpp @@ -259,6 +259,10 @@ BOOL JavascriptObject::ChangePrototype(RecyclableObject* object, RecyclableObjec // Stash away the next cache before we potentially zero out current one nextInlineCache = curInlineCache->next; + // `type` might be null (See https://github.com/chakra-core/ChakraCore/blob/0cfe82d202c0298f4bbde06070f8dbf9099946c8/lib/Runtime/Library/JavascriptFunction.cpp#L3365-L3367) + if (curInlineCache->type == nullptr) + continue; + bool clearCurrentCache = curInlineCache->type == object->GetType(); if (!clearCurrentCache) { // Check if function prototype contains old prototype From e4e231d7dc38327bbefda8fef3aed79b90965f15 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sat, 22 Oct 2022 23:49:54 +0200 Subject: [PATCH 08/12] Fix compiler error https://github.com/chakra-core/ChakraCore/pull/6857#issuecomment-1287759372 --- lib/Common/Memory/RecyclerObjectGraphDumper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Common/Memory/RecyclerObjectGraphDumper.cpp b/lib/Common/Memory/RecyclerObjectGraphDumper.cpp index 0885df3fbc1..3a2f30d6619 100644 --- a/lib/Common/Memory/RecyclerObjectGraphDumper.cpp +++ b/lib/Common/Memory/RecyclerObjectGraphDumper.cpp @@ -1,5 +1,6 @@ //------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. +// Copyright (c) ChakraCore Project Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #include "CommonMemoryPch.h" @@ -58,7 +59,7 @@ void RecyclerObjectGraphDumper::BeginDumpObject(void * objectAddress) { Assert(false); this->dumpObjectTypeInfo = nullptr; - this->dumpObjectIsArray = nullptr; + this->dumpObjectIsArray = false; } } #endif From 03ec18e82dd1d94937daeae135a95a5aa26a28aa Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Sun, 30 Oct 2022 00:13:36 +0200 Subject: [PATCH 09/12] Add trace phase --- lib/Common/ConfigFlagsList.h | 3 ++- lib/Runtime/Library/JavascriptFunction.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/Common/ConfigFlagsList.h b/lib/Common/ConfigFlagsList.h index 1777127109c..1dd29997cc6 100644 --- a/lib/Common/ConfigFlagsList.h +++ b/lib/Common/ConfigFlagsList.h @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft Corporation and contributors. All rights reserved. -// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved. +// Copyright (c) ChakraCore Project Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- @@ -331,6 +331,7 @@ PHASE(All) PHASE(RegexQc) PHASE(RegexOptBT) PHASE(InlineCache) + PHASE(IsInstInlineCacheInvalidation) PHASE(PolymorphicInlineCache) PHASE(MissingPropertyCache) PHASE(PropertyCache) // Trace caching of property lookups using PropertyString and JavascriptSymbol diff --git a/lib/Runtime/Library/JavascriptFunction.cpp b/lib/Runtime/Library/JavascriptFunction.cpp index f92a56be862..a64ad0a36d9 100644 --- a/lib/Runtime/Library/JavascriptFunction.cpp +++ b/lib/Runtime/Library/JavascriptFunction.cpp @@ -1,5 +1,6 @@ //------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. +// Copyright (c) ChakraCore Project Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #include "RuntimeLibraryPch.h" @@ -3389,8 +3390,16 @@ void __cdecl _alloca_probe_16() Assert(function != nullptr); if (inlineCache->TryGetResult(instance, function, &javascriptResult)) { +#ifdef ENABLE_TEST_HOOKS + if (PHASE_TRACE1(Js::IsInstInlineCacheInvalidationPhase)) + Output::Print(_u("CacheHit")); +#endif return javascriptResult == scriptContext->GetLibrary()->GetTrue(); } +#ifdef ENABLE_TEST_HOOKS + if (PHASE_TRACE1(Js::IsInstInlineCacheInvalidationPhase)) + Output::Print(_u("NoCacheHit")); +#endif } // If we are here, then me must have missed the cache. This may be because: From ca719c125f5d0be146d5ea9f6ed01d822409bb21 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Fri, 4 Nov 2022 12:05:17 +0100 Subject: [PATCH 10/12] New test using baseline --- test/InlineCaches/isinstanceof.baseline | 15 ++++ test/InlineCaches/isinstanceof.js | 103 +++++++++++++++++++----- test/InlineCaches/rlexe.xml | 3 +- 3 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 test/InlineCaches/isinstanceof.baseline diff --git a/test/InlineCaches/isinstanceof.baseline b/test/InlineCaches/isinstanceof.baseline new file mode 100644 index 00000000000..5297517ae33 --- /dev/null +++ b/test/InlineCaches/isinstanceof.baseline @@ -0,0 +1,15 @@ +NoCacheHit:Box:Component: false +NoCacheHit:Component:ComponentBase: true +NoCacheHit:Health:Component: true +NoCacheHit:Shape:ShapeBase: true +NoCacheHit:ShapeBase:ShapeBaseBase: true + -> Change prototype +NoCacheHitNoCacheHit:Box:Component: true true +CacheHitNoCacheHit:Component:ComponentBase: true true +CacheHitNoCacheHit:Health:Component: true true +NoCacheHitNoCacheHit:Shape:ShapeBase: false false +CacheHitNoCacheHit:ShapeBase:ShapeBaseBase: true true +==================== +NoCacheHit:Box:Circle false + -> Change prototype +CacheHitNoCacheHit:Box:Circle false false diff --git a/test/InlineCaches/isinstanceof.js b/test/InlineCaches/isinstanceof.js index e12854b1fd0..51fcfc59bbc 100644 --- a/test/InlineCaches/isinstanceof.js +++ b/test/InlineCaches/isinstanceof.js @@ -5,33 +5,92 @@ //------------------------------------------------------------------------------------------------------- // @ts-check -/// -WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js"); -const tests = [{ - name: "Clear IsInstInlineCache of 'Object.setPrototypeOf'", - body: function () { - // See https://github.com/chakra-core/ChakraCore/issues/5915 +function inherit(child, parent) { + child.prototype = Object.create(parent.prototype); + child.prototype.constructor = child; +} - function Component() { } - function Shape() { } +// #region setup "classes" +function ComponentBase() { } +function Component() { } +inherit(Component, ComponentBase); - function Box() { } - Box.prototype = Object.create(Shape.prototype); - Box.prototype.constructor = Box; +function Health() { } +inherit(Health, Component); - function checkInstanceOf(a, b) { - return a instanceof b; - } +function ShapeBaseBase() { } +function ShapeBase() { } +inherit(ShapeBase, ShapeBaseBase); +function Shape() { } +inherit(Shape, ShapeBase); - assert.isFalse(Box.prototype instanceof Component, "Box.prototype instanceof Component"); - assert.isFalse(checkInstanceOf(Box.prototype, Component), "checkInstanceOf(Box.prototype, Component)"); +function Box() { } +inherit(Box, Shape); - Object.setPrototypeOf(Shape.prototype, Component.prototype); +function Circle() { } +inherit(Circle, Shape); +// #endregion - assert.isTrue(Box.prototype instanceof Component, "Box.prototype instanceof Component"); - assert.isTrue(checkInstanceOf(Box.prototype, Component), "checkInstanceOf(Box.prototype, Component)"); - } -}]; +// #region check functions +function checkA(a, b) { + return a instanceof b; +} + +function checkB(a, b) { + return a instanceof b; +} + +function checkC(a, b) { + return a instanceof b; +} + +function checkD(a, b) { + return a instanceof b; +} + +function checkE(a, b) { + return a instanceof b; +} +// #endregion + +console.log(':Box:Component:', checkA(Box.prototype, Component)); + +console.log(':Component:ComponentBase:', checkB(Component.prototype, ComponentBase)); + +console.log(':Health:Component:', checkC(Health.prototype, Component)); + +console.log(':Shape:ShapeBase:', checkD(Shape.prototype, ShapeBase)); + +console.log(':ShapeBase:ShapeBaseBase:', checkE(ShapeBase.prototype, ShapeBaseBase)); + +console.log(" -> Change prototype"); +Object.setPrototypeOf(Shape.prototype, Component.prototype); + +// Box inherits Shape (changed) -> should invalidate cache (NoCacheHit) +console.log(':Box:Component:', checkA(Box.prototype, Component), Box.prototype instanceof Component); + +// New prototype chain remains valid (CacheHit) +console.log(':Component:ComponentBase:', checkB(Component.prototype, ComponentBase), Component.prototype instanceof ComponentBase); + +// Seperate prototype chain remains valid (CacheHit) +console.log(':Health:Component:', checkC(Health.prototype, Component), Health.prototype instanceof Component); + +// We changed that! (NoCacheHit) +console.log(':Shape:ShapeBase:', checkD(Shape.prototype, ShapeBase), Shape.prototype instanceof ShapeBase); + +// Old prototype chain remains valid (CacheHit) +console.log(':ShapeBase:ShapeBaseBase:', checkE(ShapeBase.prototype, ShapeBaseBase), ShapeBase.prototype instanceof ShapeBaseBase); + + +console.log("===================="); + + +console.log(':Box:Circle', checkA(Box.prototype, Circle)); + +console.log(" -> Change prototype"); +Object.setPrototypeOf(Circle.prototype, Shape.prototype); + +// Modifying the function (constructor) does not invalidate the cache +console.log(':Box:Circle', checkA(Box.prototype, Circle), Box.prototype instanceof Circle); -testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" }); diff --git a/test/InlineCaches/rlexe.xml b/test/InlineCaches/rlexe.xml index ebe56150a33..5ea46761428 100644 --- a/test/InlineCaches/rlexe.xml +++ b/test/InlineCaches/rlexe.xml @@ -140,7 +140,8 @@ isinstanceof.js - -args summary -endargs + -trace:IsInstInlineCacheInvalidation + isinstanceof.baseline From 2cc4bcc8c4235d7182d37e168f0f2e54fe84d307 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Fri, 4 Nov 2022 05:06:16 -0700 Subject: [PATCH 11/12] Fix style --- test/InlineCaches/rlexe.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/InlineCaches/rlexe.xml b/test/InlineCaches/rlexe.xml index 5ea46761428..7b4bddafddd 100644 --- a/test/InlineCaches/rlexe.xml +++ b/test/InlineCaches/rlexe.xml @@ -141,7 +141,7 @@ isinstanceof.js -trace:IsInstInlineCacheInvalidation - isinstanceof.baseline + isinstanceof.baseline From b6753e539144749165c9f43e64628f69236a0f24 Mon Sep 17 00:00:00 2001 From: Lukas Kurz Date: Fri, 4 Nov 2022 05:56:23 -0700 Subject: [PATCH 12/12] Prevent jit fastpath during test phase --- lib/Backend/Lower.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Backend/Lower.cpp b/lib/Backend/Lower.cpp index a4486bf8bef..6a42fc5ffb3 100644 --- a/lib/Backend/Lower.cpp +++ b/lib/Backend/Lower.cpp @@ -1533,6 +1533,10 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa break; case Js::OpCode::IsInst: +#ifdef ENABLE_TEST_HOOKS + // Don't use the fast path if we are in this phase + if (!PHASE_TRACE1(Js::IsInstInlineCacheInvalidationPhase)) +#endif this->GenerateFastIsInst(instr); instrPrev = this->LowerIsInst(instr, IR::HelperScrObj_OP_IsInst); break;