// Copyright 2020 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.

// TODO(gsathya): This test will probably break when v8 tiers up to turbofan
// from turboprop.
//
// Flags: --allow-natives-syntax --opt --no-always-opt --turboprop

var global = this;
var unique_id = 0;
// Creates a function with unique SharedFunctionInfo to ensure the feedback
// vector is unique for each test case.
function MakeFunctionWithUniqueSFI(...args) {
  assertTrue(args.length > 0);
  var body = `/* Unique comment: ${unique_id++} */ ` + args.pop();
  return new Function(...args, body);
}


//
// Load constant field from constant object directly.
//
function TestLoadFromConstantFieldOfAConstantObject(the_value, other_value) {
  function A(v) { this.v = v; }
  function O() { this.a = new A(the_value); }
  var the_object = new O();

  // Ensure that {the_object.a}'s map is not stable to complicate compiler's
  // life.
  new A(the_value).blah = 0;

  // Ensure that constant tracking is enabled for {contant_object}.
  delete global.constant_object;
  global.constant_object = the_object;
  assertEquals(the_object, constant_object);

  assertTrue(%HasFastProperties(the_object));

  // {constant_object} is known to the compiler via global property cell
  // tracking.
  var load = MakeFunctionWithUniqueSFI("return constant_object.a.v;");
  %PrepareFunctionForOptimization(load);
  load();
  load();
  %OptimizeFunctionOnNextCall(load);
  assertEquals(the_value, load());
  assertOptimized(load);
  var a = new A(other_value);
  assertTrue(%HaveSameMap(a, the_object.a));
  // Make constant field mutable by assigning another value
  // to some other instance of A.
  new A(the_value).v = other_value;
  assertTrue(%HaveSameMap(a, new A(the_value)));
  assertTrue(%HaveSameMap(a, the_object.a));
  assertOptimized(load);
  assertEquals(the_value, load());
  assertOptimized(load);
  assertEquals(the_value, load());
}

//Test constant tracking with Smi value.
(function() {
  var the_value = 42;
  var other_value = 153;
  TestLoadFromConstantFieldOfAConstantObject(the_value, other_value);
})();

// Test constant tracking with double value.
(function() {
  var the_value = 0.9;
  var other_value = 0.42;
  TestLoadFromConstantFieldOfAConstantObject(the_value, other_value);
})();

// Test constant tracking with function value.
(function() {
  var the_value = function V() {};
  var other_value = function W() {};
  TestLoadFromConstantFieldOfAConstantObject(the_value, other_value);
})();

// Test constant tracking with heap object value.
(function() {
  function V() {}
  var the_value = new V();
  var other_value = new V();
  TestLoadFromConstantFieldOfAConstantObject(the_value, other_value);
})();


//
// Load constant field from a prototype.
//
function TestLoadFromConstantFieldOfAPrototype(the_value, other_value) {
  function Proto() { this.v = the_value; }
  var the_prototype = new Proto();

  function O() {}
  O.prototype = the_prototype;
  var the_object = new O();

  // Ensure O.prototype is in fast mode by loading from its field.
  function warmup() { return new O().v; }
  %EnsureFeedbackVectorForFunction(warmup);
  warmup(); warmup(); warmup();
  assertTrue(%HasFastProperties(O.prototype));

  // The parameter object is not constant but all the values have the same
  // map and therefore the compiler knows the prototype object and can
  // optimize load of "v".
  var load = MakeFunctionWithUniqueSFI("o", "return o.v;");
  %PrepareFunctionForOptimization(load);
  load(new O());
  load(new O());
  %OptimizeFunctionOnNextCall(load);
  assertEquals(the_value, load(new O()));
  assertOptimized(load);
  // Invalidation of mutability should trigger deoptimization with a
  // "field-owner" reason.
  the_prototype.v = other_value;
  assertUnoptimized(load);
}

// Test constant tracking with Smi value.
(function() {
  var the_value = 42;
  var other_value = 153;
  TestLoadFromConstantFieldOfAPrototype(the_value, other_value);
})();

// Test constant tracking with double value.
(function() {
  var the_value = 0.9;
  var other_value = 0.42;
  TestLoadFromConstantFieldOfAPrototype(the_value, other_value);
})();

// Test constant tracking with function value.
(function() {
  var the_value = function V() {};
  var other_value = function W() {};
  TestLoadFromConstantFieldOfAPrototype(the_value, other_value);
})();

// Test constant tracking with heap object value.
(function() {
  function V() {}
  var the_value = new V();
  var other_value = new V();
  TestLoadFromConstantFieldOfAPrototype(the_value, other_value);
})();


//
// Store to constant field of a constant object.
//
function TestStoreToConstantFieldOfConstantObject(the_value, other_value) {
  function A(v) { this.v = v; }
  function O() { this.a = new A(the_value); }
  var the_object = new O();

  // Ensure that {the_object.a}'s map is not stable to complicate compiler's
  // life.
  new A(the_value).blah = 0;

  // Ensure that constant tracking is enabled for {contant_object}.
  delete global.constant_object;
  global.constant_object = the_object;
  assertEquals(the_object, constant_object);

  assertTrue(%HasFastProperties(the_object));

  // {constant_object} is known to the compiler via global property cell
  // tracking.
  var store = MakeFunctionWithUniqueSFI("v", "constant_object.a.v = v;");
  %PrepareFunctionForOptimization(store);
  store(the_value);
  store(the_value);
  %OptimizeFunctionOnNextCall(store);
  store(the_value);
  assertEquals(the_value, constant_object.a.v);
  assertOptimized(store);
  // Storing of the same value does not deoptimize.
  store(the_value);
  assertEquals(the_value, constant_object.a.v);
  assertOptimized(store);

  var a = new A(other_value);

  assertOptimized(store);
  // Storing other value deoptimizes because of failed value check.
  store(other_value);
  assertOptimized(store);
  assertEquals(other_value, constant_object.a.v);
}

// Test constant tracking with Smi values.
(function() {
  var the_value = 42;
  var other_value = 153;
  TestStoreToConstantFieldOfConstantObject(the_value, other_value);
})();

// Test constant tracking with double values.
(function() {
  var the_value = 0.9;
  var other_value = 0.42
  TestStoreToConstantFieldOfConstantObject(the_value, other_value);
})();

// Test constant tracking with function values.
(function() {
  var the_value = function V() {};
  var other_value = function W() {};
  TestStoreToConstantFieldOfConstantObject(the_value, other_value);
})();

// Test constant tracking with heap object values.
(function() {
  function V() {}
  var the_value = new V();
  var other_value = new V();
  TestStoreToConstantFieldOfConstantObject(the_value, other_value);
})();
