/*
 * Copyright (c) 2013, 2014, 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.
 *
 */

#ifndef SHARE_VM_SERVICES_MEM_TRACKER_HPP
#define SHARE_VM_SERVICES_MEM_TRACKER_HPP

#include "services/nmtCommon.hpp"
#include "utilities/nativeCallStack.hpp"


#if !INCLUDE_NMT

#define CURRENT_PC   NativeCallStack::EMPTY_STACK
#define CALLER_PC    NativeCallStack::EMPTY_STACK

class Tracker : public StackObj {
 public:
  Tracker() { }
  void record(address addr, size_t size) { }
};

class MemTracker : AllStatic {
 public:
  static inline NMT_TrackingLevel tracking_level() { return NMT_off; }
  static inline void shutdown() { }
  static inline void init() { }
  static bool check_launcher_nmt_support(const char* value) { return true; }
  static bool verify_nmt_option() { return true; }

  static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag,
    const NativeCallStack& stack, NMT_TrackingLevel level) { return mem_base; }
  static inline size_t malloc_header_size(NMT_TrackingLevel level) { return 0; }
  static inline size_t malloc_header_size(void* memblock) { return 0; }
  static inline void* malloc_base(void* memblock) { return memblock; }
  static inline void* record_free(void* memblock) { return memblock; }

  static inline void record_new_arena(MEMFLAGS flag) { }
  static inline void record_arena_free(MEMFLAGS flag) { }
  static inline void record_arena_size_change(int diff, MEMFLAGS flag) { }
  static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack,
                       MEMFLAGS flag = mtNone) { }
  static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size,
    const NativeCallStack& stack, MEMFLAGS flag = mtNone) { }
  static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { }
  static inline Tracker get_virtual_memory_uncommit_tracker() { return Tracker(); }
  static inline Tracker get_virtual_memory_release_tracker() { }
  static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { }
  static inline void record_thread_stack(void* addr, size_t size) { }
  static inline void release_thread_stack(void* addr, size_t size) { }

  static void final_report(outputStream*) { }
  static void error_report(outputStream*) { }
};

#else

#include "runtime/atomic.hpp"
#include "runtime/threadCritical.hpp"
#include "services/mallocTracker.hpp"
#include "services/virtualMemoryTracker.hpp"

extern volatile bool NMT_stack_walkable;

#define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \
                    NativeCallStack(0, true) : NativeCallStack::EMPTY_STACK)
#define CALLER_PC  ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ?  \
                    NativeCallStack(1, true) : NativeCallStack::EMPTY_STACK)

class MemBaseline;
class Mutex;

// Tracker is used for guarding 'release' semantics of virtual memory operation, to avoid
// the other thread obtains and records the same region that is just 'released' by current
// thread but before it can record the operation.
class Tracker : public StackObj {
 public:
  enum TrackerType {
     uncommit,
     release
  };

 public:
  Tracker(enum TrackerType type) : _type(type) { }
  void record(address addr, size_t size);
 private:
  enum TrackerType  _type;
  // Virtual memory tracking data structures are protected by ThreadCritical lock.
  ThreadCritical    _tc;
};

class MemTracker : AllStatic {
 public:
  static inline NMT_TrackingLevel tracking_level() {
    if (_tracking_level == NMT_unknown) {
      // No fencing is needed here, since JVM is in single-threaded
      // mode.
      _tracking_level = init_tracking_level();
      _cmdline_tracking_level = _tracking_level;
    }
    return _tracking_level;
  }

  // A late initialization, for the stuff(s) can not be
  // done in init_tracking_level(), which can NOT malloc
  // any memory.
  static void init();

  // Shutdown native memory tracking
  static void shutdown();

  // Verify native memory tracking command line option.
  // This check allows JVM to detect if compatible launcher
  // is used.
  // If an incompatible launcher is used, NMT may not be
  // able to start, even it is enabled by command line option.
  // A warning message should be given if it is encountered.
  static bool check_launcher_nmt_support(const char* value);

  // This method checks native memory tracking environment
  // variable value passed by launcher.
  // Launcher only obligates to pass native memory tracking
  // option value, but not obligates to validate the value,
  // and launcher has option to discard native memory tracking
  // option from the command line once it sets up the environment
  // variable, so NMT has to catch the bad value here.
  static bool verify_nmt_option();

  // Transition the tracking level to specified level
  static bool transition_to(NMT_TrackingLevel level);

  static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag,
    const NativeCallStack& stack, NMT_TrackingLevel level) {
    return MallocTracker::record_malloc(mem_base, size, flag, stack, level);
  }

  static inline size_t malloc_header_size(NMT_TrackingLevel level) {
    return MallocTracker::malloc_header_size(level);
  }

  static size_t malloc_header_size(void* memblock) {
    if (tracking_level() != NMT_off) {
      return MallocTracker::get_header_size(memblock);
    }
    return 0;
  }

  // To malloc base address, which is the starting address
  // of malloc tracking header if tracking is enabled.
  // Otherwise, it returns the same address.
  static void* malloc_base(void* memblock);

  // Record malloc free and return malloc base address
  static inline void* record_free(void* memblock) {
    return MallocTracker::record_free(memblock);
  }


  // Record creation of an arena
  static inline void record_new_arena(MEMFLAGS flag) {
    if (tracking_level() < NMT_summary) return;
    MallocTracker::record_new_arena(flag);
  }

  // Record destruction of an arena
  static inline void record_arena_free(MEMFLAGS flag) {
    if (tracking_level() < NMT_summary) return;
    MallocTracker::record_arena_free(flag);
  }

  // Record arena size change. Arena size is the size of all arena
  // chuncks that backing up the arena.
  static inline void record_arena_size_change(int diff, MEMFLAGS flag) {
    if (tracking_level() < NMT_summary) return;
    MallocTracker::record_arena_size_change(diff, flag);
  }

  static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack,
    MEMFLAGS flag = mtNone) {
    if (tracking_level() < NMT_summary) return;
    if (addr != NULL) {
      ThreadCritical tc;
      // Recheck to avoid potential racing during NMT shutdown
      if (tracking_level() < NMT_summary) return;
      VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag);
    }
  }

  static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size,
    const NativeCallStack& stack, MEMFLAGS flag = mtNone) {
    if (tracking_level() < NMT_summary) return;
    if (addr != NULL) {
      ThreadCritical tc;
      if (tracking_level() < NMT_summary) return;
      VirtualMemoryTracker::add_reserved_region((address)addr, size,
        stack, flag, true);
    }
  }

  static inline void record_virtual_memory_commit(void* addr, size_t size,
    const NativeCallStack& stack) {
    if (tracking_level() < NMT_summary) return;
    if (addr != NULL) {
      ThreadCritical tc;
      if (tracking_level() < NMT_summary) return;
      VirtualMemoryTracker::add_committed_region((address)addr, size, stack);
    }
  }

  static inline Tracker get_virtual_memory_uncommit_tracker() {
    assert(tracking_level() >= NMT_summary, "Check by caller");
    return Tracker(Tracker::uncommit);
  }

  static inline Tracker get_virtual_memory_release_tracker() {
    assert(tracking_level() >= NMT_summary, "Check by caller");
    return Tracker(Tracker::release);
  }

  static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) {
    if (tracking_level() < NMT_summary) return;
    if (addr != NULL) {
      ThreadCritical tc;
      if (tracking_level() < NMT_summary) return;
      VirtualMemoryTracker::set_reserved_region_type((address)addr, flag);
    }
  }

  static inline void record_thread_stack(void* addr, size_t size) {
    if (tracking_level() < NMT_summary) return;
    if (addr != NULL) {
      // uses thread stack malloc slot for book keeping number of threads
      MallocMemorySummary::record_malloc(0, mtThreadStack);
      record_virtual_memory_reserve_and_commit(addr, size, CALLER_PC, mtThreadStack);
    }
  }

  static inline void release_thread_stack(void* addr, size_t size) {
    if (tracking_level() < NMT_summary) return;
    if (addr != NULL) {
      // uses thread stack malloc slot for book keeping number of threads
      MallocMemorySummary::record_free(0, mtThreadStack);
      ThreadCritical tc;
      if (tracking_level() < NMT_summary) return;
      VirtualMemoryTracker::remove_released_region((address)addr, size);
    }
  }

  // Query lock is used to synchronize the access to tracking data.
  // So far, it is only used by JCmd query, but it may be used by
  // other tools.
  static inline Mutex* query_lock() { return _query_lock; }

  // Make a final report or report for hs_err file.
  static void error_report(outputStream* output) {
    if (tracking_level() >= NMT_summary) {
      report(true, output);  // just print summary for error case.
    }
   }

  static void final_report(outputStream* output) {
    NMT_TrackingLevel level = tracking_level();
    if (level >= NMT_summary) {
      report(level == NMT_summary, output);
    }
  }


  // Stored baseline
  static inline MemBaseline& get_baseline() {
    return _baseline;
  }

  static NMT_TrackingLevel cmdline_tracking_level() {
    return _cmdline_tracking_level;
  }

  static void tuning_statistics(outputStream* out);

 private:
  static NMT_TrackingLevel init_tracking_level();
  static void report(bool summary_only, outputStream* output);

 private:
  // Tracking level
  static volatile NMT_TrackingLevel   _tracking_level;
  // If NMT option value passed by launcher through environment
  // variable is valid
  static bool                         _is_nmt_env_valid;
  // command line tracking level
  static NMT_TrackingLevel            _cmdline_tracking_level;
  // Stored baseline
  static MemBaseline      _baseline;
  // Query lock
  static Mutex*           _query_lock;
};

#endif // INCLUDE_NMT

#endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP

