| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Flags: --allow-natives-syntax --nostress-opt --track-field-types |
| // Flags: --opt --no-always-opt |
| |
| (function() { |
| var o = { text: "Hello World!" }; |
| function A() { |
| // Assign twice to make the field non-constant. |
| this.a = {text: 'foo'}; |
| this.a = o; |
| } |
| function readA(x) { |
| return x.a; |
| } |
| %PrepareFunctionForOptimization(readA); |
| var a = new A(); |
| assertUnoptimized(readA); |
| readA(a); readA(a); readA(a); |
| %OptimizeFunctionOnNextCall(readA); |
| assertEquals(readA(a), o); |
| assertOptimized(readA); |
| |
| var b = new A(); |
| b.b = o; |
| assertEquals(readA(b), o); |
| assertUnoptimized(readA); |
| %PrepareFunctionForOptimization(readA); |
| %OptimizeFunctionOnNextCall(readA); |
| assertEquals(readA(a), o); |
| assertOptimized(readA); |
| assertEquals(readA(a), o); |
| assertEquals(readA(b), o); |
| assertOptimized(readA); |
| |
| function readAFromB(x) { |
| return x.a; |
| } |
| assertUnoptimized(readAFromB); |
| %PrepareFunctionForOptimization(readAFromB); |
| readAFromB(b); readAFromB(b); readAFromB(b); |
| %OptimizeFunctionOnNextCall(readAFromB); |
| assertEquals(readAFromB(b), o); |
| assertOptimized(readAFromB); |
| |
| var c = new A(); |
| c.c = o; |
| assertOptimized(readA); |
| assertOptimized(readAFromB); |
| c.a = [1]; |
| assertUnoptimized(readA); |
| assertUnoptimized(readAFromB); |
| %PrepareFunctionForOptimization(readA); |
| %PrepareFunctionForOptimization(readAFromB); |
| assertEquals(readA(a), o); |
| assertEquals(readA(b), o); |
| assertEquals(readA(c), [1]); |
| assertEquals(readAFromB(b), o); |
| |
| %OptimizeFunctionOnNextCall(readA); |
| assertEquals(readA(a), o); |
| %OptimizeFunctionOnNextCall(readAFromB); |
| assertEquals(readAFromB(b), o); |
| assertOptimized(readA); |
| a.a = [1]; |
| assertEquals(readA(a), [1]); |
| assertEquals(readA(b), o); |
| assertEquals(readA(c), [1]); |
| assertOptimized(readA); |
| b.a = [1]; |
| assertEquals(readA(a), [1]); |
| assertEquals(readA(b), [1]); |
| assertEquals(readA(c), [1]); |
| assertOptimized(readA); |
| assertOptimized(readAFromB); |
| })(); |
| |
| (function() { |
| function A() { this.x = 0; } |
| A.prototype = {y: 20}; |
| function B(o) { return o.a.y; } |
| function C() { this.a = new A(); } |
| %EnsureFeedbackVectorForFunction(C); |
| |
| %PrepareFunctionForOptimization(B); |
| B(new C()); |
| B(new C()); |
| %OptimizeFunctionOnNextCall(B); |
| var c = new C(); |
| assertEquals(20, B(c)); |
| assertOptimized(B); |
| c.a.y = 10; |
| assertEquals(10, B(c)); |
| assertUnoptimized(B); |
| |
| %PrepareFunctionForOptimization(B); |
| var c = new C(); |
| %OptimizeFunctionOnNextCall(B); |
| assertEquals(20, B(c)); |
| assertOptimized(B); |
| c.a.y = 30; |
| assertEquals(30, B(c)); |
| assertOptimized(B); |
| })(); |
| |
| (function() { |
| var x = new Object(); |
| x.a = 1 + "Long string that results in a cons string"; |
| x = JSON.parse('{"a":"Short"}'); |
| })(); |
| |
| (function() { |
| var x = {y: {z: 1}}; |
| x.y.z = 1.1; |
| })(); |
| |
| (function() { |
| function Foo(x) { this.x = x; } |
| var f0 = new Foo({x: 0}); |
| f0.x = {x: 0}; // make Foo.x non-constant here. |
| var f1 = new Foo({x: 1}); |
| var f2 = new Foo({x: 2}); |
| var f3 = new Foo({x: 3}); |
| function readX(f) { return f.x.x; } |
| %PrepareFunctionForOptimization(readX); |
| assertEquals(readX(f1), 1); |
| assertEquals(readX(f2), 2); |
| assertUnoptimized(readX); |
| %OptimizeFunctionOnNextCall(readX); |
| assertEquals(readX(f3), 3); |
| assertOptimized(readX); |
| function writeX(f, x) { f.x = x; } |
| %PrepareFunctionForOptimization(writeX); |
| writeX(f1, {x: 11}); |
| writeX(f2, {x: 22}); |
| assertUnoptimized(writeX); |
| assertEquals(readX(f1), 11); |
| assertEquals(readX(f2), 22); |
| assertOptimized(readX); |
| %OptimizeFunctionOnNextCall(writeX); |
| writeX(f3, {x: 33}); |
| assertEquals(readX(f3), 33); |
| assertOptimized(readX); |
| assertOptimized(writeX); |
| function addY(f, y) { f.y = y; } |
| writeX(f1, {a: "a"}); |
| assertUnoptimized(readX); |
| assertUnoptimized(writeX); |
| })(); |
| |
| (function() { |
| function Narf(x) { this.x = x; } |
| var f1 = new Narf(1); |
| var f2 = new Narf(2); |
| var f3 = new Narf(3); |
| function baz(f, y) { f.y = y; } |
| %PrepareFunctionForOptimization(baz); |
| baz(f1, {b: 9}); |
| baz(f2, {b: 9}); |
| baz(f2, {b: 9}); |
| %OptimizeFunctionOnNextCall(baz); |
| baz(f2, {b: 9}); |
| baz(f3, {a: -1}); |
| assertUnoptimized(baz); |
| })(); |
| |
| (function() { |
| function Foo(x) { this.x = x; this.a = x; } |
| function Bar(x) { this.x = x; this.b = x; } |
| function readA(o) { return o.x.a; } |
| var f = new Foo({a:1}); |
| var b = new Bar({a:2}); |
| %PrepareFunctionForOptimization(readA); |
| assertEquals(readA(f), 1); |
| assertEquals(readA(b), 2); |
| assertEquals(readA(f), 1); |
| assertEquals(readA(b), 2); |
| %OptimizeFunctionOnNextCall(readA); |
| assertEquals(readA(f), 1); |
| assertEquals(readA(b), 2); |
| assertOptimized(readA); |
| f.a.y = 0; |
| assertUnoptimized(readA); |
| })(); |