// 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 --opt --no-always-opt //////////////////////////////////////////////////////////////////////////////// // This is a variant of regress-99540-1.js that does not rely on concurrent // recompilation. //////////////////////////////////////////////////////////////////////////////// function mkbar() { return function(x) { x.p } } var bar = mkbar(); function foo(x) { bar(x) } %PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(bar); %PrepareFunctionForOptimization(mkbar); // Create map transitions such that a's final map is not stable. var dummy = []; dummy.p = 0; dummy.q = 0; var a = []; a.p = 42; var b = []; b.p = 42; // Warm-up. foo(a); foo(a); // Trigger optimization of bar, based on PACKED_SMI_ELEMENTS feedback. %OptimizeFunctionOnNextCall(bar); bar(a); assertOptimized(bar); %PrepareFunctionForOptimization(bar); // Change a's map from PACKED_SMI_ELEMENTS to PACKED_ELEMENTS and run new // instance of mkbar() in the interpreter s.t. bar's load feedback changes // accordingly (thanks to feedback vector sharing). a[0] = {}; mkbar()(a); assertOptimized(bar); // If we were to call the optimized bar now, it would deopt. // Instead we trigger optimization of foo, which will inline bar (this time // based on the new PACKED_ELEMENTS map. assertOptimized(bar); %OptimizeFunctionOnNextCall(foo); assertOptimized(bar); foo(a); assertOptimized(bar); assertOptimized(foo); %PrepareFunctionForOptimization(foo); // Now call the optimized foo on an object that has the old PACKED_SMI_ELEMENTS // map. This will lead to an eager deopt of foo when the inlined bar sees that // old map. foo(b); assertUnoptimized(foo); assertOptimized(bar); // Now ensure there is no deopt-loop. There used to be a deopt-loop because, as // a result of over-eager checkpoint elimination, we used to deopt into foo // (right before the call to bar) rather than into bar (right before the load). %OptimizeFunctionOnNextCall(foo); foo(b); assertOptimized(foo);