/*
 * Copyright (c) 2021, 2022 SAP SE. All rights reserved.
 * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "precompiled.hpp"
#include "jvm_io.h"
#include "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "services/nmtPreInit.hpp"
#include "utilities/debug.hpp"
#include "utilities/ostream.hpp"
#include "unittest.hpp"

// This tests the NMTPreInitAllocationTable hash table used to store C-heap allocations before NMT initialization ran.

static size_t small_random_nonzero_size() {
  // We keep the sizes random but not too random; the more regular the sizes, the
  // more regular the malloc return pointers and the better we see how our hash
  // function copes in the NMT preinit lu table.
  switch (os::random() % 4) {
  case 0: return 0x10;
  case 1: return 0x42;
  case 2: return 0x20;
  case 3: return 0x80;
  }
  return 1;
}

//#define VERBOSE

static void print_and_check_table(NMTPreInitAllocationTable& table, int expected_num_entries) {
  char tmp[256];
  stringStream ss(tmp, sizeof(tmp));
  char expected[256];
  jio_snprintf(expected, sizeof(expected), "entries: %d", expected_num_entries);
  table.print_state(&ss);
  EXPECT_EQ(::strncmp(tmp, expected, strlen(expected)), 0);
#ifdef VERBOSE
  tty->print_raw(tmp);
  tty->cr();
#endif
  DEBUG_ONLY(table.verify();)
}

TEST_VM(NMTPreInit, stress_test_map) {
  NMTPreInitAllocationTable table;
  const int num_allocs = 32 * K; // about factor 100 more than normally expected
  NMTPreInitAllocation** allocations = NEW_C_HEAP_ARRAY(NMTPreInitAllocation*, num_allocs, mtTest);

  // Fill table with allocations
  for (int i = 0; i < num_allocs; i++) {
    NMTPreInitAllocation* a = NMTPreInitAllocation::do_alloc(small_random_nonzero_size());
    table.add(a);
    allocations[i] = a;
  }

  print_and_check_table(table, num_allocs);

  // look them all up
  for (int i = 0; i < num_allocs; i++) {
    const NMTPreInitAllocation* a = table.find(allocations[i]->payload);
    ASSERT_EQ(a, allocations[i]);
  }

  // Randomly realloc
  for (int j = 0; j < num_allocs/2; j++) {
    int pos = os::random() % num_allocs;
    NMTPreInitAllocation* a1 = allocations[pos];
    NMTPreInitAllocation* a2 = table.find_and_remove(a1->payload);
    ASSERT_EQ(a1, a2);
    NMTPreInitAllocation* a3 = NMTPreInitAllocation::do_reallocate(a2, small_random_nonzero_size());
    table.add(a3);
    allocations[pos] = a3;
  }

  print_and_check_table(table, num_allocs);

  // look them all up
  for (int i = 0; i < num_allocs; i++) {
    const NMTPreInitAllocation* a = table.find(allocations[i]->payload);
    ASSERT_EQ(a, allocations[i]);
  }

  // free all
  for (int i = 0; i < num_allocs; i++) {
    NMTPreInitAllocation* a = table.find_and_remove(allocations[i]->payload);
    ASSERT_EQ(a, allocations[i]);
    NMTPreInitAllocation::do_free(a);
    allocations[i] = NULL;
  }

  print_and_check_table(table, 0);

  FREE_C_HEAP_ARRAY(NMTPreInitAllocation*, allocations);
}

#ifdef ASSERT
// Test that we will assert if the lookup table is seriously over-booked.
TEST_VM_ASSERT_MSG(NMTPreInit, assert_on_lu_table_overflow, ".*NMT preinit lookup table degenerated.*") {
  NMTPreInitAllocationTable table;
  const int num_allocs = 400 * 1000; // anything above ~250K entries should trigger the assert (note: normal number of entries is ~500)
  for (int i = 0; i < num_allocs; i++) {
    NMTPreInitAllocation* a = NMTPreInitAllocation::do_alloc(1);
    table.add(a);
  }
#ifdef VERBOSE
  table.print_state(tty);
  tty->cr();
#endif
  table.verify();
}
#endif // ASSERT
