/*
 * Copyright (c) 2012, 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_BASELINE_HPP
#define SHARE_VM_SERVICES_MEM_BASELINE_HPP

#if INCLUDE_NMT

#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
#include "services/mallocSiteTable.hpp"
#include "services/mallocTracker.hpp"
#include "services/nmtCommon.hpp"
#include "services/virtualMemoryTracker.hpp"
#include "utilities/linkedlist.hpp"

typedef LinkedListIterator<MallocSite>                   MallocSiteIterator;
typedef LinkedListIterator<VirtualMemoryAllocationSite>  VirtualMemorySiteIterator;
typedef LinkedListIterator<ReservedMemoryRegion>         VirtualMemoryAllocationIterator;

/*
 * Baseline a memory snapshot
 */
class MemBaseline VALUE_OBJ_CLASS_SPEC {
 public:
  enum BaselineThreshold {
    SIZE_THRESHOLD = K        // Only allocation size over this threshold will be baselined.
  };

  enum BaselineType {
    Not_baselined,
    Summary_baselined,
    Detail_baselined
  };

  enum SortingOrder {
    by_address,   // by memory address
    by_size,      // by memory size
    by_site       // by call site where the memory is allocated from
  };

 private:
  // Summary information
  MallocMemorySnapshot   _malloc_memory_snapshot;
  VirtualMemorySnapshot  _virtual_memory_snapshot;

  size_t               _class_count;

  // Allocation sites information
  // Malloc allocation sites
  LinkedListImpl<MallocSite>                  _malloc_sites;

  // All virtual memory allocations
  LinkedListImpl<ReservedMemoryRegion>        _virtual_memory_allocations;

  // Virtual memory allocations by allocation sites, always in by_address
  // order
  LinkedListImpl<VirtualMemoryAllocationSite> _virtual_memory_sites;

  SortingOrder         _malloc_sites_order;
  SortingOrder         _virtual_memory_sites_order;

  BaselineType         _baseline_type;

 public:
  // create a memory baseline
  MemBaseline():
    _baseline_type(Not_baselined),
    _class_count(0) {
  }

  bool baseline(bool summaryOnly = true);

  BaselineType baseline_type() const { return _baseline_type; }

  MallocMemorySnapshot* malloc_memory_snapshot() {
    return &_malloc_memory_snapshot;
  }

  VirtualMemorySnapshot* virtual_memory_snapshot() {
    return &_virtual_memory_snapshot;
  }

  MallocSiteIterator malloc_sites(SortingOrder order);
  VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order);

  // Virtual memory allocation iterator always returns in virtual memory
  // base address order.
  VirtualMemoryAllocationIterator virtual_memory_allocations() {
    assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline");
    return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head());
  }

  // Total reserved memory = total malloc'd memory + total reserved virtual
  // memory
  size_t total_reserved_memory() const {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    size_t amount = _malloc_memory_snapshot.total() +
           _virtual_memory_snapshot.total_reserved();
    return amount;
  }

  // Total committed memory = total malloc'd memory + total committed
  // virtual memory
  size_t total_committed_memory() const {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    size_t amount = _malloc_memory_snapshot.total() +
           _virtual_memory_snapshot.total_committed();
    return amount;
  }

  size_t total_arena_memory() const {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    return _malloc_memory_snapshot.total_arena();
  }

  size_t malloc_tracking_overhead() const {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    MemBaseline* bl = const_cast<MemBaseline*>(this);
    return bl->_malloc_memory_snapshot.malloc_overhead()->size();
  }

  MallocMemory* malloc_memory(MEMFLAGS flag) {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    return _malloc_memory_snapshot.by_type(flag);
  }

  VirtualMemory* virtual_memory(MEMFLAGS flag) {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    return _virtual_memory_snapshot.by_type(flag);
  }


  size_t class_count() const {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    return _class_count;
  }

  size_t thread_count() const {
    assert(baseline_type() != Not_baselined, "Not yet baselined");
    return _malloc_memory_snapshot.thread_count();
  }

  // reset the baseline for reuse
  void reset() {
    _baseline_type = Not_baselined;
    // _malloc_memory_snapshot and _virtual_memory_snapshot are copied over.
    _class_count  = 0;

    _malloc_sites.clear();
    _virtual_memory_sites.clear();
    _virtual_memory_allocations.clear();
  }

 private:
  // Baseline summary information
  bool baseline_summary();

  // Baseline allocation sites (detail tracking only)
  bool baseline_allocation_sites();

  // Aggregate virtual memory allocation by allocation sites
  bool aggregate_virtual_memory_allocation_sites();

  // Sorting allocation sites in different orders
  // Sort allocation sites in size order
  void malloc_sites_to_size_order();
  // Sort allocation sites in call site address order
  void malloc_sites_to_allocation_site_order();

  // Sort allocation sites in reserved size order
  void virtual_memory_sites_to_size_order();
  // Sort allocation sites in call site address order
  void virtual_memory_sites_to_reservation_site_order();
};

#endif // INCLUDE_NMT

#endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP
