/*
 * Copyright (C) 2017 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.
 */

public class Main {

  // Note that this is testing we haven't intrinsified the byte[] arraycopy version.
  // Once we eventually start doing it, we will need to re-adjust this test.

  /// CHECK-START-X86: void Main.typedCopy(java.lang.Object, byte[]) disassembly (after)
  /// CHECK: InvokeStaticOrDirect method_name:java.lang.System.arraycopy intrinsic:SystemArrayCopy
  /// CHECK-NOT:    call
  /// CHECK: InvokeStaticOrDirect method_name:java.lang.System.arraycopy intrinsic:SystemArrayCopyByte
  /// CHECK-NOT:    call
  /// CHECK: ReturnVoid
  public static void typedCopy(Object o, byte[] foo) {
    System.arraycopy(o, 1, o, 0, 1);
    System.arraycopy((Object)foo, 1, (Object)foo, 0, 1);  // Don't use the @hide byte[] overload.
  }

  public static void untypedCopy(Object o, Object foo) {
    System.arraycopy(o, 1, o, 0, 1);
    System.arraycopy(foo, 1, foo, 0, 1);
  }

  // Test that we still do the optimization after inlining.

  /// CHECK-START-X86: void Main.untypedCopyCaller(java.lang.Object, byte[]) disassembly (after)
  /// CHECK: InvokeStaticOrDirect method_name:java.lang.System.arraycopy intrinsic:SystemArrayCopy
  /// CHECK-NOT:    call
  /// CHECK: InvokeStaticOrDirect method_name:java.lang.System.arraycopy intrinsic:SystemArrayCopyByte
  /// CHECK-NOT:    call
  /// CHECK: ReturnVoid
  public static void untypedCopyCaller(Object o, byte[] array) {
    untypedCopy(o, array);
  }

  public static void assertEquals(Object one, Object two) {
    if (one != two) {
      throw new Error("Expected " + one + ", got " + two);
    }
  }

  public static void main(String[] args) {
    // Simple checks.
    byte[] a = new byte[2];
    Object[] o = new Object[2];

    o[0] = a;
    o[1] = o;
    a[0] = 1;
    a[1] = 2;

    untypedCopyCaller(o, a);
    assertEquals(o[0], o);
    assertEquals(o[1], o);
    assertEquals(a[0], (byte)2);
    assertEquals(a[1], (byte)2);

    o[0] = a;
    o[1] = o;
    a[0] = 1;
    a[1] = 2;

    typedCopy(o, a);
    assertEquals(o[0], o);
    assertEquals(o[1], o);
    assertEquals(a[0], (byte)2);
    assertEquals(a[1], (byte)2);
  }
}
