/*
 * Copyright (c) 2019, 2020, Red Hat, Inc. 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_GC_SHENANDOAH_SHENANDOAHNMETHOD_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHNMETHOD_HPP

#include "code/nmethod.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahLock.hpp"
#include "gc/shenandoah/shenandoahPadding.hpp"
#include "memory/allocation.hpp"
#include "utilities/growableArray.hpp"

// ShenandoahNMethod tuple records the internal locations of oop slots within reclocation stream in
// the nmethod. This allows us to quickly scan the oops without doing the nmethod-internal scans,
// that sometimes involves parsing the machine code. Note it does not record the oops themselves,
// because it would then require handling these tuples as the new class of roots.
class ShenandoahNMethod : public CHeapObj<mtGC> {
private:
  nmethod* const          _nm;
  oop**                   _oops;
  int                     _oops_count;
  bool                    _has_non_immed_oops;
  bool                    _unregistered;
  ShenandoahReentrantLock _lock;

public:
  ShenandoahNMethod(nmethod *nm, GrowableArray<oop*>& oops, bool has_non_immed_oops);
  ~ShenandoahNMethod();

  inline nmethod* nm() const;
  inline ShenandoahReentrantLock* lock();
  inline void oops_do(OopClosure* oops, bool fix_relocations = false);
  // Update oops when the nmethod is re-registered
  void update();

  inline bool is_unregistered() const;

  static ShenandoahNMethod* for_nmethod(nmethod* nm);
  static inline ShenandoahReentrantLock* lock_for_nmethod(nmethod* nm);

  static void heal_nmethod(nmethod* nm);
  static inline void heal_nmethod_metadata(ShenandoahNMethod* nmethod_data);
  static inline void disarm_nmethod(nmethod* nm);

  static inline ShenandoahNMethod* gc_data(nmethod* nm);
  static inline void attach_gc_data(nmethod* nm, ShenandoahNMethod* gc_data);

  void assert_correct() NOT_DEBUG_RETURN;
  void assert_same_oops(bool allow_dead = false) NOT_DEBUG_RETURN;

private:
  static void detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& _has_non_immed_oops);
};

class ShenandoahNMethodTable;

// ShenandoahNMethodList holds registered nmethod data. The list is reference counted.
class ShenandoahNMethodList : public CHeapObj<mtGC> {
private:
  ShenandoahNMethod** _list;
  const int           _size;
  uint                _ref_count;

private:
  ~ShenandoahNMethodList();

public:
  ShenandoahNMethodList(int size);

  // Reference counting with CoceCache_lock held
  ShenandoahNMethodList* acquire();
  void release();

  // Transfer content from other list to 'this' list, up to the limit
  void transfer(ShenandoahNMethodList* const other, int limit);

  inline int size() const;
  inline ShenandoahNMethod** list() const;
  inline ShenandoahNMethod* at(int index) const;
  inline void set(int index, ShenandoahNMethod* snm);
};

// An opaque snapshot of current nmethod table for iteration
class ShenandoahNMethodTableSnapshot : public CHeapObj<mtGC> {
  friend class ShenandoahNMethodTable;
private:
  ShenandoahHeap* const       _heap;
  ShenandoahNMethodList*      _list;
  /* snapshot iteration limit */
  int                         _limit;

  shenandoah_padding(0);
  volatile size_t       _claimed;
  shenandoah_padding(1);

public:
  ShenandoahNMethodTableSnapshot(ShenandoahNMethodTable* table);
  ~ShenandoahNMethodTableSnapshot();

  void parallel_blobs_do(CodeBlobClosure *f);
  void concurrent_nmethods_do(NMethodClosure* cl);
};

class ShenandoahNMethodTable : public CHeapObj<mtGC> {
  friend class ShenandoahNMethodTableSnapshot;
private:
  enum {
    minSize = 1024
  };

  ShenandoahHeap* const  _heap;
  ShenandoahNMethodList* _list;

  int                    _index;
  ShenandoahLock         _lock;
  int                    _itr_cnt;

public:
  ShenandoahNMethodTable();
  ~ShenandoahNMethodTable();

  void register_nmethod(nmethod* nm);
  void unregister_nmethod(nmethod* nm);

  bool contain(nmethod* nm) const;
  int length() const { return _index; }

  // Table iteration support
  ShenandoahNMethodTableSnapshot* snapshot_for_iteration();
  void finish_iteration(ShenandoahNMethodTableSnapshot* snapshot);

  void assert_nmethods_correct() NOT_DEBUG_RETURN;
private:
  // Rebuild table and replace current one
  void rebuild(int size);

  bool is_full() const {
    assert(_index <= _list->size(), "Sanity");
    return _index == _list->size();
  }

  ShenandoahNMethod* at(int index) const;
  int  index_of(nmethod* nm) const;
  void remove(int index);
  void append(ShenandoahNMethod* snm);

  inline bool iteration_in_progress() const;
  void wait_until_concurrent_iteration_done();

  // Logging support
  void log_register_nmethod(nmethod* nm);
  void log_unregister_nmethod(nmethod* nm);
};

class ShenandoahConcurrentNMethodIterator {
private:
  ShenandoahNMethodTable*         const _table;
  ShenandoahNMethodTableSnapshot*       _table_snapshot;

public:
  ShenandoahConcurrentNMethodIterator(ShenandoahNMethodTable* table);

  void nmethods_do_begin();
  void nmethods_do(NMethodClosure* cl);
  void nmethods_do_end();
};

#endif // SHARE_GC_SHENANDOAH_SHENANDOAHNMETHOD_HPP
