From d3accb0c9cb39357bb874e83f3ccad45f0577851 Mon Sep 17 00:00:00 2001 From: chakrabot Date: Fri, 4 Aug 2017 03:02:07 -0700 Subject: [PATCH] [Merge Microsoft/Chakracore@95f497c17f] [1.6>1.7] [MERGE #3463 @ricobbe] OS#11712101 Hoist CheckObjType out of loops only when the operand's containing object type is also invariant Merge pull request #3463 from ricobbe:CheckObjType-hoist-fix Check object type of argument to CheckObjType before hoisting it out of a loop, to avoid hoisting it over a DeleteFld that invalidates the type. --- deps/chakrashim/core/lib/Backend/GlobOpt.cpp | 15 ++++++++++ .../test/Optimizer/HoistCheckObjType.baseline | 1 + .../core/test/Optimizer/HoistCheckObjType.js | 30 +++++++++++++++++++ deps/chakrashim/core/test/Optimizer/rlexe.xml | 7 +++++ 4 files changed, 53 insertions(+) create mode 100644 deps/chakrashim/core/test/Optimizer/HoistCheckObjType.baseline create mode 100644 deps/chakrashim/core/test/Optimizer/HoistCheckObjType.js diff --git a/deps/chakrashim/core/lib/Backend/GlobOpt.cpp b/deps/chakrashim/core/lib/Backend/GlobOpt.cpp index 7089d2ec4ab..22c2c6999dc 100644 --- a/deps/chakrashim/core/lib/Backend/GlobOpt.cpp +++ b/deps/chakrashim/core/lib/Backend/GlobOpt.cpp @@ -16232,6 +16232,21 @@ GlobOpt::OptIsInvariant( { allowNonPrimitives = true; } + break; + case Js::OpCode::CheckObjType: + // Bug 11712101: If the operand is a field, ensure that its containing object type is invariant + // before hoisting -- that is, don't hoist a CheckObjType over a DeleteFld on that object. + // (CheckObjType only checks the operand and its immediate parent, so we don't need to go + // any farther up the object graph.) + Assert(instr->GetSrc1()); + PropertySym *propertySym = instr->GetSrc1()->AsPropertySymOpnd()->GetPropertySym(); + if (propertySym->HasObjectTypeSym()) { + StackSym *objectTypeSym = propertySym->GetObjectTypeSym(); + if (!this->OptIsInvariant(objectTypeSym, block, loop, this->CurrentBlockData()->FindValue(objectTypeSym), true, true)) { + return false; + } + } + break; } diff --git a/deps/chakrashim/core/test/Optimizer/HoistCheckObjType.baseline b/deps/chakrashim/core/test/Optimizer/HoistCheckObjType.baseline new file mode 100644 index 00000000000..2409a1cb4da --- /dev/null +++ b/deps/chakrashim/core/test/Optimizer/HoistCheckObjType.baseline @@ -0,0 +1 @@ +[object Object],[object Object],[object Object] diff --git a/deps/chakrashim/core/test/Optimizer/HoistCheckObjType.js b/deps/chakrashim/core/test/Optimizer/HoistCheckObjType.js new file mode 100644 index 00000000000..8a82ef960e0 --- /dev/null +++ b/deps/chakrashim/core/test/Optimizer/HoistCheckObjType.js @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +var GiantPrintArray = []; +function makeArrayLength() { +} +var obj0 = {}; +var obj1 = {}; +var arrObj0 = {}; +var func3 = function () { + protoObj0._x = {}; + for (var v0 = 0; v0 < 3; v0++) { + delete arrObj0.length; + protoObj0.length = protoObj0._x; + } + GiantPrintArray.push(arrObj0.length); +}; +obj0.method1 = func3; +obj1.method0 = obj0.method1; +obj1.method1 = obj1.method0; +arrObj0.length = makeArrayLength(); +protoObj0 = arrObj0; +for (var _strvar13 in obj1) { + obj0.method1(); +} +var uniqobj3 = [obj1]; +uniqobj3[0].method1(); +WScript.Echo(GiantPrintArray); diff --git a/deps/chakrashim/core/test/Optimizer/rlexe.xml b/deps/chakrashim/core/test/Optimizer/rlexe.xml index 08fc986e6ac..01634faf32a 100644 --- a/deps/chakrashim/core/test/Optimizer/rlexe.xml +++ b/deps/chakrashim/core/test/Optimizer/rlexe.xml @@ -1417,4 +1417,11 @@ -lic:1 -off:simplejit -bgjit- + + + HoistCheckObjType.js + HoistCheckObjType.baseline + -maxinterpretcount:1 -maxsimplejitruncount:1 + +