/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// TODO: Add more tests after we can inline functions with calls.

class ClassWithoutFinals {
  /// CHECK-START: void ClassWithoutFinals.<init>() inliner (after)
  /// CHECK-NOT: ConstructorFence
  public ClassWithoutFinals() {}
}

class ClassWithFinals {
  public final int x;
  public ClassWithFinals obj;
  public static boolean doThrow = false;

  public ClassWithFinals(boolean cond) {
    x = 1;
    throw new RuntimeException();
    // should not inline this constructor
  }

  /// CHECK-START: void ClassWithFinals.<init>() inliner (after)
  /// CHECK:      ConstructorFence
  /// CHECK-NOT:  ConstructorFence

  /*
   * Check that the correct assembly instructions are selected for a Store/Store fence.
   *
   * - ARM variants:   DMB ISHST (store-store fence for inner shareable domain)
   * - Intel variants: no-op (store-store does not need a fence).
   */

  /// CHECK-START-ARM64: void ClassWithFinals.<init>() disassembly (after)
  /// CHECK:      ConstructorFence
  /// CHECK-NEXT: dmb ishst

  /// CHECK-START-ARM: void ClassWithFinals.<init>() disassembly (after)
  /// CHECK:      ConstructorFence
  /// CHECK-NEXT: dmb ishst

  /// CHECK-START-X86_64: void ClassWithFinals.<init>() disassembly (after)
  /// CHECK:      ConstructorFence
  /// CHECK-NOT:  {{[slm]}}fence

  /// CHECK-START-X86: void ClassWithFinals.<init>() disassembly (after)
  /// CHECK:      ConstructorFence
  /// CHECK-NOT:  {{[slm]}}fence
  public ClassWithFinals() {
    // Exactly one constructor barrier.
    // Note: Do not store 0 as that can be eliminated together with the constructor
    // barrier by the code pattern substitution in the inliner.
    x = 1;
  }

  /// CHECK-START: void ClassWithFinals.<init>(int) inliner (after)
  /// CHECK: <<This:l\d+>>            ParameterValue
  /// CHECK: <<NewInstance:l\d+>>     NewInstance
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<This>>]
  /// CHECK-NOT:                      ConstructorFence
  public ClassWithFinals(int x) {
    // This should have exactly three barriers:
    //   - one for the new-instance
    //   - one for the constructor
    //   - one for the `new` which should be inlined.
    obj = new ClassWithFinals();
    this.x = x;
  }
}

class InheritFromClassWithFinals extends ClassWithFinals {
  /// CHECK-START: void InheritFromClassWithFinals.<init>() inliner (after)
  /// CHECK: <<This:l\d+>>            ParameterValue
  /// CHECK:                          ConstructorFence [<<This>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void InheritFromClassWithFinals.<init>() inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public InheritFromClassWithFinals() {
    // Should inline the super constructor.
    //
    // Exactly one constructor barrier here.
  }

  /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) inliner (after)
  /// CHECK:      InvokeStaticOrDirect

  /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) inliner (after)
  /// CHECK-NOT:  ConstructorFence
  public InheritFromClassWithFinals(boolean cond) {
    super(cond);
    // should not inline the super constructor
  }

  /// CHECK-START: void InheritFromClassWithFinals.<init>(int) inliner (after)
  /// CHECK: <<This:l\d+>>            ParameterValue
  /// CHECK-DAG: <<NewHere:l\d+>>     NewInstance klass:InheritFromClassWithFinals
  /// CHECK-DAG:                      ConstructorFence [<<This>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewHere>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewHere>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void InheritFromClassWithFinals.<init>(int) inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public InheritFromClassWithFinals(int unused) {
    // super();  // implicitly the first invoke in this constructor.
    //   Should inline the super constructor and insert a constructor fence there.

    // Should inline the new instance call (barrier); and add another one
    // because the superclass has finals.
    new InheritFromClassWithFinals();
  }
}

class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals {
  final int y;

  /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() inliner (after)
  /// CHECK: <<This:l\d+>>            ParameterValue
  /// CHECK:                          ConstructorFence [<<This>>]
  /// CHECK:                          ConstructorFence [<<This>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() inliner (after)
  /// CHECK-NOT: InvokeStaticOrDirect
  public HaveFinalsAndInheritFromClassWithFinals() {
    // Should inline the super constructor and keep the memory barrier.
    y = 0;
  }

  /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) inliner (after)
  /// CHECK: <<This:l\d+>>            ParameterValue
  /// CHECK:                          InvokeStaticOrDirect
  /// CHECK:                          ConstructorFence [<<This>>]
  /// CHECK-NOT:                      ConstructorFence
  public HaveFinalsAndInheritFromClassWithFinals(boolean cond) {
    super(cond);
    // should not inline the super constructor
    y = 0;
  }

  /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) inliner (after)
  /// CHECK: <<This:l\d+>>            ParameterValue
  /// CHECK-DAG: <<NewHF:l\d+>>       NewInstance klass:HaveFinalsAndInheritFromClassWithFinals
  /// CHECK-DAG: <<NewIF:l\d+>>       NewInstance klass:InheritFromClassWithFinals
  /// CHECK-DAG:                      ConstructorFence [<<This>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewHF>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewHF>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewHF>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewIF>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewIF>>]
  /// CHECK-DAG:                      ConstructorFence [<<This>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public HaveFinalsAndInheritFromClassWithFinals(int unused) {
    // super()
    // -- Inlined super constructor, insert memory barrier here.
    y = 0;

    // Should inline new instance and keep both memory barriers.
    // One more memory barrier for new-instance.
    // (3 total for this new-instance #1)
    new HaveFinalsAndInheritFromClassWithFinals();
    // Should inline new instance and have exactly one barrier.
    // One more barrier for new-instance.
    // (2 total for this new-instance #2)
    new InheritFromClassWithFinals();

    // -- End of constructor, insert memory barrier here to freeze 'y'.
  }
}

public class Main {

  /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() inliner (after)
  /// CHECK:      InvokeStaticOrDirect

  /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() inliner (after)
  /// CHECK: <<NewInstance:l\d+>>     NewInstance
  /// CHECK:                          ConstructorFence [<<NewInstance>>]
  /// CHECK-NOT:                      ConstructorFence
  public static ClassWithFinals noInlineNoConstructorBarrier() {
    // Exactly one barrier for the new-instance.
    return new ClassWithFinals(false);
    // should not inline the constructor
  }

  /// CHECK-START: void Main.inlineNew() inliner (after)
  /// CHECK: <<NewInstance:l\d+>>     NewInstance
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void Main.inlineNew() inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static void inlineNew() {
    // Exactly 2 barriers. One for new-instance, one for constructor with finals.
    new ClassWithFinals();
  }

  /// CHECK-START: void Main.inlineNew1() inliner (after)
  /// CHECK: <<NewInstance:l\d+>>     NewInstance
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void Main.inlineNew1() inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static void inlineNew1() {
    new InheritFromClassWithFinals();
  }

  /// CHECK-START: void Main.inlineNew2() inliner (after)
  /// CHECK: <<NewInstance:l\d+>>     NewInstance
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void Main.inlineNew2() inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static void inlineNew2() {
    new HaveFinalsAndInheritFromClassWithFinals();
  }

  /// CHECK-START: void Main.inlineNew3() inliner (after)
  /// CHECK: <<NewInstance:l\d+>>     NewInstance
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
  /// CHECK-NOT:                      ConstructorFence
  /// CHECK: <<NewInstance2:l\d+>>    NewInstance
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
  /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
  /// CHECK-NOT:                      ConstructorFence

  /// CHECK-START: void Main.inlineNew3() inliner (after)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static void inlineNew3() {
    new HaveFinalsAndInheritFromClassWithFinals();
    new HaveFinalsAndInheritFromClassWithFinals();
  }

  static int[] mCodePointsEmpty = new int[0];

  /// CHECK-START: void Main.testNewString() inliner (after)
  /// CHECK-NOT:  ConstructorFence
  /// CHECK:      InvokeStaticOrDirect method_load_kind:StringInit
  /// CHECK-NOT:  ConstructorFence
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static void testNewString() {
    // Strings are special because of StringFactory hackeries.
    //
    // Assume they handle their own fencing internally in the StringFactory.
    int[] codePoints = null;
    String some_new_string = new String(mCodePointsEmpty, 0, 0);
  }

  public static void main(String[] args) {}
}
