| // Copyright 2019 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 |
| |
| // Check that load elimination on const-marked fields works |
| (function() { |
| function maybe_sideeffect(b) { return 42; } |
| |
| %NeverOptimizeFunction(maybe_sideeffect); |
| |
| class B { |
| constructor(x) { |
| this.value = x; |
| } |
| } |
| %EnsureFeedbackVectorForFunction(B); |
| |
| |
| function lit_const_smi() { |
| let b = { value: 123 }; |
| maybe_sideeffect(b); |
| let v1 = b.value; |
| maybe_sideeffect(b); |
| let v2 = b.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, 123)); |
| } |
| |
| %PrepareFunctionForOptimization(lit_const_smi); |
| lit_const_smi(); lit_const_smi(); |
| %OptimizeFunctionOnNextCall(lit_const_smi); lit_const_smi(); |
| |
| |
| function lit_const_object() { |
| let o = {x: 123}; |
| let b = { value: o }; |
| maybe_sideeffect(b); |
| let v1 = b.value; |
| maybe_sideeffect(b); |
| let v2 = b.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, o)); |
| } |
| |
| %PrepareFunctionForOptimization(lit_const_object); |
| lit_const_object(); lit_const_object(); |
| %OptimizeFunctionOnNextCall(lit_const_object); lit_const_object(); |
| |
| |
| function lit_computed_smi(k) { |
| let kk = 2 * k; |
| let b = { value: kk }; |
| maybe_sideeffect(b); |
| let v1 = b.value; |
| maybe_sideeffect(b); |
| let v2 = b.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, kk)); |
| } |
| |
| %PrepareFunctionForOptimization(lit_computed_smi); |
| lit_computed_smi(1); lit_computed_smi(2); |
| %OptimizeFunctionOnNextCall(lit_computed_smi); lit_computed_smi(3); |
| |
| // TODO(bmeurer): Fix const tracking for double fields in object literals |
| // lit_computed_smi(1.1); lit_computed_smi(2.2); |
| // %OptimizeFunctionOnNextCall(lit_computed_smi); lit_computed_smi(3.3); |
| |
| |
| function lit_param_object(k) { |
| let b = { value: k }; |
| maybe_sideeffect(b); |
| let v1 = b.value; |
| maybe_sideeffect(b); |
| let v2 = b.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, k)); |
| } |
| |
| %PrepareFunctionForOptimization(lit_param_object); |
| lit_param_object({x: 1}); lit_param_object({x: 2}); |
| %OptimizeFunctionOnNextCall(lit_param_object); lit_param_object({x: 3}); |
| |
| |
| function nested_lit_param(k) { |
| let b = { x: { value: k } }; |
| maybe_sideeffect(b); |
| let v1 = b.x.value; |
| maybe_sideeffect(b); |
| let v2 = b.x.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, k)); |
| } |
| |
| %PrepareFunctionForOptimization(nested_lit_param); |
| nested_lit_param(1); nested_lit_param(2); |
| %OptimizeFunctionOnNextCall(nested_lit_param); nested_lit_param(3); |
| |
| // TODO(bmeurer): Fix const tracking for double fields in object literals |
| // nested_lit_param(1.1); nested_lit_param(2.2); |
| // %OptimizeFunctionOnNextCall(nested_lit_param); nested_lit_param(3.3); |
| |
| |
| function nested_lit_param_object(k) { |
| let b = { x: { value: k } }; |
| maybe_sideeffect(b); |
| let v1 = b.x.value; |
| maybe_sideeffect(b); |
| let v2 = b.x.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, k)); |
| } |
| |
| %PrepareFunctionForOptimization(nested_lit_param_object); |
| nested_lit_param_object({x: 1}); nested_lit_param_object({x: 2}); |
| %OptimizeFunctionOnNextCall(nested_lit_param_object); |
| nested_lit_param_object({x: 3}); |
| |
| |
| function inst_param(k) { |
| let b = new B(k); |
| maybe_sideeffect(b); |
| let v1 = b.value; |
| maybe_sideeffect(b); |
| let v2 = b.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, k)); |
| } |
| |
| %EnsureFeedbackVectorForFunction(B); |
| %PrepareFunctionForOptimization(inst_param); |
| inst_param(1); inst_param(2); |
| %OptimizeFunctionOnNextCall(inst_param); inst_param(3); |
| |
| // TODO(gsps): Reenable once we fully support const field information |
| // tracking in the presence of pointer compression. |
| // inst_param(1.1); inst_param(2.2); |
| // %OptimizeFunctionOnNextCall(inst_param); inst_param(3.3); |
| |
| %PrepareFunctionForOptimization(inst_param); |
| inst_param({x: 1}); inst_param({x: 2}); |
| %OptimizeFunctionOnNextCall(inst_param); inst_param({x: 3}); |
| |
| |
| function inst_computed(k) { |
| let kk = 2 * k; |
| let b = new B(kk); |
| maybe_sideeffect(b); |
| let v1 = b.value; |
| maybe_sideeffect(b); |
| let v2 = b.value; |
| %TurbofanStaticAssert(Object.is(v1, v2)); |
| %TurbofanStaticAssert(Object.is(v2, kk)); |
| } |
| |
| %EnsureFeedbackVectorForFunction(B); |
| %PrepareFunctionForOptimization(inst_computed); |
| inst_computed(1); inst_computed(2); |
| %OptimizeFunctionOnNextCall(inst_computed); inst_computed(3); |
| |
| %PrepareFunctionForOptimization(inst_computed); |
| inst_computed(1.1); inst_computed(2.2); |
| %OptimizeFunctionOnNextCall(inst_computed); inst_computed(3.3); |
| })(); |