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

class Foo {
  volatile Object bar;
}

public class Main {

  public static void main(String[] args) {
    Main main = new Main();
    main.test();
    System.out.println("passed");
  }

  // Check that no explicit null check is emitted for the field load of volatile
  // field `Foo.bar` before entering the Baker read barrier thunk.
  //
  // Note: We cannot check the ARM64 assembly code of the Baker read barrier
  // thunk code, as it is not emitted in the CFG output.
  //
  /// CHECK-START-ARM64: void Main.test() disassembly (after)
  /// CHECK:       <<Foo:l\d+>> InstanceFieldGet [{{l\d+}}] field_name:Main.foo field_type:Reference loop:<<Loop:B\d+>>
  /// CHECK:       NullCheck [<<Foo>>] dex_pc:<<PC:\d+>> loop:<<Loop>>
  /// CHECK-NEXT:  InstanceFieldGet [<<Foo>>] dex_pc:<<PC>> field_name:Foo.bar field_type:Reference loop:<<Loop>>
  /* The following following Checker assertions are only valid when the compiler is emitting Baker
     read barriers, i.e. when ART is using the Concurrent Copying (CC) garbage collector.

     TODO(b/283392413, b/283780888): Re-enable the following Checker assertions (by replacing the
     double forward slash comments with triple forward slash ones) when b/283780888 is resolved.

  // CHECK-NEXT:      add w<<BaseRegNum:\d+>>, {{w\d+}}, #0x8 (8)
  // CHECK-NEXT:      adr lr, #+0x{{c|10}}
  // The following instruction (generated by
  // `art::arm64::CodeGeneratorARM64::EmitBakerReadBarrierCbnz`) checks the
  // Marking Register (X20) and goes into the Baker read barrier thunk if MR is
  // not null. The null offset (#+0x0) in the CBNZ instruction is a placeholder
  // for the offset to the Baker read barrier thunk (which is not yet set when
  // the CFG output is emitted).
  // CHECK-NEXT:      cbnz x20, #+0x0
  // CHECK-NEXT:      ldar {{w\d+}}, [x<<BaseRegNum>>]
  */

  public void test() {
    // Continually check that reading field `foo.bar` throws a
    // NullPointerException while allocating over 64 MiB of memory (with heap
    // size limited to 16 MiB), in order to increase memory pressure and
    // eventually trigger a concurrent garbage collection, which will start by
    // putting the GC in marking mode and enable read barriers (when the
    // Concurrent Copying collector is used).
    for (int i = 0; i != 64 * 1024; ++i) {
      allocateAtLeast1KiB();
      try {
        // Read volatile field `bar` of `foo`, which is null, and is expected
        // to produce a NullPointerException. On ARM64, this is implemented as a
        // load-acquire (LDAR instruction).
        //
        // When the Concurrent Copying GC is marking, read barriers are enabled
        // and the field load executes code from a Baker read barrier thunk.
        // On ARM64, there used to be a bug in this thunk for the load-acquire
        // case, where an explicit null check was missing, triggering an
        // unhandled SIGSEGV when trying to load the lock word from the volatile
        // field (b/140507091).
        Object foo_bar = foo.bar;
      } catch (NullPointerException e) {
        continue;
      }
      // We should not be here.
      throw new Error("Expected NullPointerException");
    }
  }

  // Allocate at least 1 KiB of memory on the managed heap.
  // Retain some allocated memory and release old allocations so that the
  // garbage collector has something to do.
  public static void allocateAtLeast1KiB() {
    memory[allocationIndex] = new Object[1024 / 4];
    ++allocationIndex;
    if (allocationIndex == memory.length) {
      allocationIndex = 0;
    }
  }

  public static Object[] memory = new Object[1024];
  public static int allocationIndex = 0;

  private Foo foo;

}
