/*
 * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates.
 * 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.
 *
 */

#if defined(LINUX) || defined(_WIN64) || defined(__APPLE__)

#include "gc/shared/collectedHeap.hpp"
#include "logging/logAsyncWriter.hpp"
#include "memory/allocation.hpp"
#include "memory/universe.hpp"
#include "memory/resourceArea.hpp"
#include "nmt/memTag.hpp"
#include "nmt/memTagBitmap.hpp"
#include "nmt/memMapPrinter.hpp"
#include "nmt/memTracker.hpp"
#include "nmt/virtualMemoryTracker.hpp"
#include "runtime/nonJavaThread.hpp"
#include "runtime/osThread.hpp"
#include "runtime/thread.hpp"
#include "runtime/threadSMR.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
#include "utilities/permitForbiddenFunctions.hpp"

// Note: throughout this code we will use the term "VMA" for OS system level memory mapping

/// NMT mechanics

// Short, clear, descriptive names for all possible markers. Note that we only expect to see
// those that have been used with mmap. Flags left out are printed with their nmt tags name.
#define NMT_FLAGS_DO(f) \
  /* mem_tag, short, description */ \
  f(mtGCCardSet,      "CARDTBL", "GC Card table") \
  f(mtClassShared,    "CDS", "CDS archives") \
  f(mtClass,          "CLASS", "Class Space") \
  f(mtCode,           "CODE", "Code Heap") \
  f(mtGC,             "GC", "GC support data (e.g. bitmaps)") \
  f(mtInternal,       "INTERN", "Internal") \
  f(mtJavaHeap,       "JAVAHEAP", "Java Heap") \
  f(mtOther,          "JDK", "allocated by JDK libraries other than VM") \
  f(mtMetaspace,      "META", "Metaspace nodes (non-class)") \
  f(mtSafepoint,      "POLL", "Polling pages") \
  f(mtThreadStack,    "STACK", "(known) Thread Stack") \
  f(mtTest,           "TEST", "JVM internal test mappings")
  //end

static const char* get_shortname_for_mem_tag(MemTag mem_tag) {
#define DO(t, shortname, text) if (t == mem_tag) return shortname;
  NMT_FLAGS_DO(DO)
#undef DO
  return NMTUtil::tag_to_enum_name(mem_tag);
}

/// NMT virtual memory

static bool range_intersects(const void* from1, const void* to1, const void* from2, const void* to2) {
  return MAX2(from1, from2) < MIN2(to1, to2);
}

// A Cache that correlates range with MemTag, optimized to be iterated quickly
// (cache friendly).
class CachedNMTInformation : public VirtualMemoryWalker {
  struct Range { const void* from; const void* to; };
  // We keep ranges apart from flags since that prevents the padding a combined
  // structure would have, and it allows for faster iteration of ranges since more
  // of them fit into a cache line.
  Range* _ranges;
  MemTag* _mem_tags;
  size_t _count, _capacity;
  mutable size_t _last;

public:
  CachedNMTInformation() : _ranges(nullptr), _mem_tags(nullptr),
                           _count(0), _capacity(0), _last(0) {}

  ~CachedNMTInformation() {
    permit_forbidden_function::free(_ranges);
    permit_forbidden_function::free(_mem_tags);
  }

  bool add(const void* from, const void* to, MemTag mem_tag) {
    // We rely on NMT regions being sorted by base
    assert(_count == 0 || (from >= _ranges[_count - 1].to), "NMT regions unordered?");
    // we can just fold two regions if they are adjacent and have the same mem_tag.
    if (_count > 0 && from == _ranges[_count - 1].to && mem_tag == _mem_tags[_count - 1]) {
      _ranges[_count - 1].to = to;
      return true;
    }
    if (_count == _capacity) {
      // Enlarge if needed
      const size_t new_capacity = MAX2((size_t)4096, 2 * _capacity);
      // Unfortunately, we need to allocate manually, raw, since we must prevent NMT deadlocks.
      _ranges = (Range*)permit_forbidden_function::realloc(_ranges, new_capacity * sizeof(Range));
      _mem_tags = (MemTag*)permit_forbidden_function::realloc(_mem_tags, new_capacity * sizeof(MemTag));
      if (_ranges == nullptr || _mem_tags == nullptr) {
        // In case of OOM lets make no fuss. Just return.
        return false;
      }
      _capacity = new_capacity;
    }
    assert(_capacity > _count, "Sanity");
    _ranges[_count] = Range { from, to };
    _mem_tags[_count] = mem_tag;
    _count++;
    return true;
  }

  // Given a vma [from, to), find all regions that intersect with this vma and
  // return their collective flags.
  MemTagBitmap lookup(const void* from, const void* to) const {
    assert(from <= to, "Sanity");
    // We optimize for sequential lookups. Since this class is used when a list
    // of OS mappings is scanned (VirtualQuery, /proc/pid/maps), and these lists
    // are usually sorted in order of addresses, ascending.
    if (to <= _ranges[_last].from) {
      // the range is to the right of the given section, we need to re-start the search
      _last = 0;
    }
    MemTagBitmap bm;
    for(uintx i = _last; i < _count; i++) {
      if (range_intersects(from, to, _ranges[i].from, _ranges[i].to)) {
        bm.set_tag(_mem_tags[i]);
      } else if (to <= _ranges[i].from) {
        _last = i;
        break;
      }
    }
    return bm;
  }

  bool do_allocation_site(const ReservedMemoryRegion* rgn) override {
    // Cancel iteration if we run out of memory (add returns false);
    return add(rgn->base(), rgn->end(), rgn->mem_tag());
  }

  // Iterate all NMT virtual memory regions and fill this cache.
  bool fill_from_nmt() {
    return VirtualMemoryTracker::walk_virtual_memory(this);
  }
};

/////// Thread information //////////////////////////

// Given a VMA [from, to) and a thread, check if vma intersects with thread stack
static bool vma_touches_thread_stack(const void* from, const void* to, const Thread* t) {
  // Java thread stacks (and sometimes also other threads) have guard pages. Therefore they typically occupy
  // at least two distinct neighboring VMAs. Therefore we typically have a 1:n relationshipt between thread
  // stack and vma.
  // Very rarely however is a VMA backing a thread stack folded together with another adjacent VMA by the
  // kernel. That can happen, e.g., for non-java threads that don't have guard pages.
  // Therefore we go for the simplest way here and check for intersection between VMA and thread stack.
  // Note it is possible to encounter a brand new thread that has not yet initialized its stack fields.
  return t->stack_base_or_null() != nullptr && range_intersects(from, to, (const void*)t->stack_end(), (const void*)t->stack_base());
}

struct GCThreadClosure : public ThreadClosure {
  bool _found;
  uintx _tid;
  const void* const _from;
  const void* const _to;
  GCThreadClosure(const void* from, const void* to) : _found(false), _tid(0), _from(from), _to(to) {}
  void do_thread(Thread* t) override {
    if (_tid == 0 && t != nullptr && vma_touches_thread_stack(_from, _to, t)) {
      _found = true;
      _tid = t->osthread()->thread_id();
      // lemme stooop! No way to signal stop :(
    }
  }
};

static void print_thread_details(uintx thread_id, const char* name, outputStream* st) {
  // avoid commas and spaces in output to ease post-processing via awk
  char tmp[64];
  stringStream ss(tmp, sizeof(tmp));
  ss.print(":%zu-%s", (uintx)thread_id, name);
  for (int i = 0; tmp[i] != '\0'; i++) {
    if (!isalnum(tmp[i])) {
      tmp[i] = '-';
    }
  }
  st->print_raw(tmp);
}

// Given a region [from, to), if it intersects a known thread stack, print detail infos about that thread.
static void print_thread_details_for_supposed_stack_address(const void* from, const void* to, outputStream* st) {

  ResourceMark rm;

#define HANDLE_THREAD(T)                                                        \
  if (T != nullptr && vma_touches_thread_stack(from, to, T)) {                  \
    print_thread_details((uintx)(T->osthread()->thread_id()), T->name(), st);   \
    return;                                                                     \
  }
  for (JavaThreadIteratorWithHandle jtiwh; JavaThread* t = jtiwh.next(); ) {
    HANDLE_THREAD(t);
  }
  HANDLE_THREAD(VMThread::vm_thread());
  HANDLE_THREAD(WatcherThread::watcher_thread());
  HANDLE_THREAD(AsyncLogWriter::instance());
#undef HANDLE_THREAD

  if (Universe::heap() != nullptr) {
    GCThreadClosure cl(from, to);
    Universe::heap()->gc_threads_do(&cl);
    if (cl._found) {
      print_thread_details(cl._tid, "GC Thread", st);
    }
  }
}

///////////////

MappingPrintSession::MappingPrintSession(outputStream* st, const CachedNMTInformation& nmt_info) :
    _out(st), _nmt_info(nmt_info)
{}

void MappingPrintSession::print_nmt_flag_legend() const {
#define DO(flag, shortname, text) _out->print_cr("%10s: %s", shortname, text);
  NMT_FLAGS_DO(DO)
#undef DO
}

bool MappingPrintSession::print_nmt_info_for_region(const void* vma_from, const void* vma_to) const {
  int num_printed = 0;
  // print NMT information, if available
  if (MemTracker::enabled()) {
    // Correlate vma region (from, to) with NMT region(s) we collected previously.
    const MemTagBitmap flags = _nmt_info.lookup(vma_from, vma_to);
    if (flags.has_any()) {
      for (int i = 0; i < mt_number_of_tags; i++) {
        const MemTag mem_tag = (MemTag)i;
        if (flags.has_tag(mem_tag)) {
          if (num_printed > 0) {
            _out->put(',');
          }
          _out->print("%s", get_shortname_for_mem_tag(mem_tag));
          if (mem_tag == mtThreadStack) {
            print_thread_details_for_supposed_stack_address(vma_from, vma_to, _out);
          }
          num_printed++;
        }
      }
    }
  }
  return num_printed > 0;
}

void MemMapPrinter::print_all_mappings(outputStream* st) {
  CachedNMTInformation nmt_info;
  st->print_cr("Memory mappings:");
  // Prepare NMT info cache. But only do so if we print individual mappings,
  // otherwise, we won't need it and can save that work.
  if (MemTracker::enabled()) {
    nmt_info.fill_from_nmt();
  } else {
    st->print_cr("NMT is disabled. VM info not available.");
  }
  MappingPrintSession session(st, nmt_info);
  pd_print_all_mappings(session);
}

#endif // LINUX
