Explorar o código

Invariant check for a propertySym before loading a property from it in the landing pad. OS #17516086

Rajat Dua %!s(int64=7) %!d(string=hai) anos
pai
achega
d1bae7fe64
Modificáronse 3 ficheiros con 95 adicións e 0 borrados
  1. 7 0
      lib/Backend/GlobOpt.cpp
  2. 82 0
      test/PRE/bug0.js
  3. 6 0
      test/PRE/rlexe.xml

+ 7 - 0
lib/Backend/GlobOpt.cpp

@@ -17187,6 +17187,13 @@ GlobOpt::PRE::InsertSymDefinitionInLandingPad(StackSym * sym, Loop * loop, Sym *
 
             BasicBlock* loopTail = loop->GetAnyTailBlock();
             Value * valueOnBackEdge = loopTail->globOptData.FindValue(propSym);
+            
+            // If o.x is not invariant in the loop, we can't use the preloaded value of o.x.y in the landing pad
+            Value * valueInLandingPad = loop->landingPad->globOptData.FindValue(propSym);
+            if (valueOnBackEdge->GetValueNumber() != valueInLandingPad->GetValueNumber())
+            {
+                return false;
+            }
 
             *objPtrCopyPropSym = valueOnBackEdge->GetValueInfo()->GetSymStore();
 

+ 82 - 0
test/PRE/bug0.js

@@ -0,0 +1,82 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+if (this.WScript && this.WScript.LoadScriptFile) { // Check for running in ch
+    this.WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
+}
+
+var tests = [
+    {
+        name: "test0",
+        body: function () {
+            function bar()
+            {
+                o = {x:2};
+            }
+            o = {x:1}
+            function test0()
+            {
+                var b;
+                for(var i=0;i<2;i++)
+                {
+                    b = o.x <<= bar();
+                }
+                assert.areEqual(2, b);
+            }
+            test0();
+            test0();
+            o = {x:1};
+            test0();
+        }
+    },
+    {
+        name: "test1",
+        body: function () {
+            var obj2 = {};
+            var i32 = new Int32Array();
+            var func0 = function () {
+                return obj2;
+            };
+            Object.prototype.prop5 = 1;
+            var a;
+            for (var __loopvar0 = 4; __loopvar0 > 0; __loopvar0--) 
+            {
+                function func7(arg1) {
+                    this.prop2 = arg1;
+                }
+                obj2 = new func7(obj2.prop5--);
+            }
+    
+            assert.areEqual(1, obj2.prop2);
+        }
+    },
+    {
+        name: "test2",
+        body: function (){
+            function makeArrayLength(x) {
+                if (!isNaN(x)) {
+                    return Math.floor(x) & 65535;
+                }
+            }
+            var obj0 = {};
+            var c = 1;
+            obj0.length = makeArrayLength(4294967295);
+            
+            for (; obj0.length--; c++) 
+            {
+                obj0 = {
+                    method1: function () {
+                        return function v1() {
+                            ({ nd0: { method1: obj0 } } );
+                        };
+                    }
+                };
+            }
+            assert.areEqual(2, c);
+        }
+    }
+];
+testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });
+

+ 6 - 0
test/PRE/rlexe.xml

@@ -8,4 +8,10 @@
       <compile-flags>-testtrace:fieldcopyprop -oopjit-</compile-flags>
     </default>
   </test> 
+  <test>
+    <default>
+      <files>bug0.js</files>
+      <compile-flags>-args summary -endargs</compile-flags>
+    </default>
+  </test>
 </regress-exe>