/*
 * 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.
 */

import AAA.Derived;

public class Main {
    public static void main(String[] args) {
        try {
            // Allocate memory for the "AAA.Derived" class name before eating memory.
            String aaaDerivedName = "AAA.Derived";
            System.out.println("Eating all memory.");
            // Resolve VMClassLoader before eating all the memory since we can not fail
            // initialization of boot classpath classes.
            Class.forName("java.lang.VMClassLoader");
            Object memory = eatAllMemory();

            // This test assumes that Derived is not yet resolved. In some configurations
            // (notably interp-ac), Derived is already resolved by verifying Main at run
            // time. Therefore we cannot assume that we get a certain `value` and need to
            // simply check for consistency, i.e. `value == another_value`.
            int value = 0;
            try {
                // If the ArtMethod* is erroneously left in the DexCache, this
                // shall succeed despite the class Derived being unresolved so
                // far. Otherwise, we shall throw OOME trying to resolve it.
                value = Derived.foo();
            } catch (OutOfMemoryError e) {
                value = -1;
            }
            int another_value = 0;
            try {
                // For comparison, try to resolve the class Derived directly.
                Class.forName(aaaDerivedName, false, Main.class.getClassLoader());
                another_value = 42;
            } catch (OutOfMemoryError e) {
                another_value = -1;
            }
            boolean memoryWasAllocated = (memory != null);
            memory = null;
            System.out.println("memoryWasAllocated = " + memoryWasAllocated);
            System.out.println("match: " + (value == another_value));
            if (value != another_value || (value != -1 && value != 42)) {
                // Mismatch or unexpected value, print additional debugging information.
                System.out.println("value: " + value);
                System.out.println("another_value: " + another_value);
            }
        } catch (Throwable t) {
            t.printStackTrace(System.out);
        }
    }

    private static int exhaustJavaHeap(Object[] data, int index, int size) {
        Runtime.getRuntime().gc();
        // Let out-of-bound exception be thrown if we go past the array length. This should
        // never happen if the logic in the caller is right. The exception acts as an assertion.
        while (size != 0) {
            try {
                data[index] = new byte[size];
                ++index;
            } catch (OutOfMemoryError oome) {
                size /= 2;
            }
        }
        return index;
    }

    public static Object eatAllMemory() {
      Object[] result = null;
      int size = 1000000;
      // Make sure that there is no reclaimable memory in the heap. Otherwise we may throw
      // OOME to prevent GC thrashing, even if later allocations may succeed.
      Runtime.getRuntime().gc();
      System.runFinalization();
      // NOTE: There is a GC invocation in exhaustJavaHeap. So we don't need one here.

      while (result == null && size != 0) {
          try {
              result = new Object[size];
          } catch (OutOfMemoryError oome) {
              size /= 2;
          }
      }
      if (result != null) {
          int index = 0;
          // Repeat to ensure there is no space left on the heap.
          index = exhaustJavaHeap(result, index, size);
          index = exhaustJavaHeap(result, index, /*size*/ 4);
          index = exhaustJavaHeap(result, index, /*size*/ 4);
      }
      return result;
  }
}
