From 4b19819510b4efacb0377122b02bb7878ec8f761 Mon Sep 17 00:00:00 2001 From: rhuanjl Date: Wed, 14 Apr 2021 23:29:04 +0100 Subject: [PATCH] Double counted copy-prop syms hit FailFast - copy prop'd syms can be referenced by key and value - both key and value can be in the unrestorableSymbols list - When restoring from the value remove the key from the list also - Also check whether needed based on the value's liveness not key --- lib/Backend/LinearScan.cpp | 4 +++- test/es6/async-jit-bugs.js | 33 +++++++++++++++++++++++++++++++++ test/es6/generator-jit-bugs.js | 20 ++++++++++++++++++-- test/es6/rlexe.xml | 21 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 test/es6/async-jit-bugs.js diff --git a/lib/Backend/LinearScan.cpp b/lib/Backend/LinearScan.cpp index 3f852a87d44..7108d0a9e43 100644 --- a/lib/Backend/LinearScan.cpp +++ b/lib/Backend/LinearScan.cpp @@ -5135,8 +5135,10 @@ void LinearScan::GeneratorBailIn::BuildBailInSymbolList( if (unrestorableSymbols.TestAndClear(value->m_id)) { - if (this->NeedsReloadingSymWhenBailingIn(copyPropSym.Key())) + if (this->NeedsReloadingSymWhenBailingIn(copyPropSym.Value())) { + // we're restoring this sym based on the value also remove the key from unrestorableSymbols + unrestorableSymbols.Clear(key->m_id); BailInSymbol bailInSym(key->m_id /* fromByteCodeRegSlot */, value->m_id /* toBackendId */); bailInSymbols->PrependNode(this->func->m_alloc, bailInSym); } diff --git a/test/es6/async-jit-bugs.js b/test/es6/async-jit-bugs.js new file mode 100644 index 00000000000..6dee055cc71 --- /dev/null +++ b/test/es6/async-jit-bugs.js @@ -0,0 +1,33 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +function main() { + const v2 = [13.37,13.37,13.37,13.37,13.37]; + async function v4(v5,v6,v7,v8) { + const v10 = 0; + for (let v14 = 0; v14 < 8; v14++) { + v5["vEBD7ei78q"] = v14; + } + for (let v16 = 1; v16 < 1337; v16++) { + const v17 = v2.__proto__; + const v23 = [13.37,13.37,-2.2250738585072014e-308,13.37,13.37]; + const v24 = v23.length; + const v25 = "-4294967296"; + const v26 = 7; + function* v28(v29,v30,v31,...v32) {} + let v33 = -2.2250738585072014e-308; + const v34 = v28(v33,Object,Object); + const v35 = 13.37; + const v36 = 2384357829; + const v37 = await "-4294967296"; + const v38 = --v33; + } + const v39 = 128; + print("pass") + } +v4("vEBD7ei78q"); +} +main(); diff --git a/test/es6/generator-jit-bugs.js b/test/es6/generator-jit-bugs.js index 00018f5f1ae..2594cc92d4f 100644 --- a/test/es6/generator-jit-bugs.js +++ b/test/es6/generator-jit-bugs.js @@ -4,8 +4,9 @@ // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- -let results = 0; -let test = 0; +// Simpler mini-test harness to avoid any complicating factors when testing these jit bugs +var results = 0; +var test = 0; const verbose = WScript.Arguments[0] != "summary"; function check(actual, expected) { @@ -90,6 +91,7 @@ check(gen4.next().value, 1); check(gen4.next().value, 2); check(gen4.next().value, 3); +// Test 5 - scope slots fail to load inside for-in loop title("Load Scope Slots in presence of for-in"); function* gf5(v1) { for(v0 in v1) { @@ -106,6 +108,7 @@ check(gen5.next().value, undefined); check(gen5.next().value, undefined); check(gen5.next().value, undefined); +// Test 6 - scope slots used in loop control have invalid values title("Load Scope Slots used in loop control"); function* gf6 () { for (let v1 = 0; v1 < 1000; ++v1) { @@ -121,6 +124,7 @@ check(gen6.next().value, 1); check(gen6.next().value, 2); check(gen6.next().value, 3); +// Test 7 - storing scoped slot from loop control in array title("Load Scope Slots used in loop control and captured indirectly"); function* gf7(v1) { for (const v2 in v1) { @@ -136,5 +140,17 @@ check(gen7.next().value, 1); check(gen7.next().value, 2); check(gen7.next().value, undefined); +// Test 8 - copy prop'd sym is counted as two values - hits bookkeeping FailFast +title("Copy prop sym double counted in unrestorable symbols hits FailFast"); +function* gf8() { + var v8 = 1.1; + yield* []; + yield {v8}; +} + +check(gf8().next().value.v8, 1.1); +check(gf8().next().value.v8, 1.1); +check(gf8().next().value.v8, 1.1); + print("pass"); diff --git a/test/es6/rlexe.xml b/test/es6/rlexe.xml index e079f4c46eb..25bf6969978 100644 --- a/test/es6/rlexe.xml +++ b/test/es6/rlexe.xml @@ -153,6 +153,27 @@ exclude_nonative, exclude_dynapogo + + + async-jit-bugs.js + -JitES6Generators -args summary -endargs + exclude_nonative + + + + + async-jit-bugs.js + -JitES6Generators -off:simplejit -args summary -endargs + exclude_nonative + + + + + async-jit-bugs.js + -JitES6Generators -off:fulljit -args summary -endargs + exclude_nonative, exclude_dynapogo + + proto_basic.js