/*
 * Copyright (c) 2019, 2023, 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_JVMCI_METADATAHANDLES_HPP
#define SHARE_JVMCI_METADATAHANDLES_HPP

#include "oops/constantPool.hpp"
#include "oops/metadata.hpp"
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/os.hpp"

#ifdef ASSERT
#define METADATA_TRACK_NAMES
#endif

struct _jmetadata {
 private:
  Metadata* _value;
#ifdef METADATA_TRACK_NAMES
  // Debug data for tracking stale metadata
  const char* _name;
#endif

 public:
  Metadata* value() { return _value; }

#ifdef METADATA_TRACK_NAMES
  void initialize() {
    _value = nullptr;
    _name = nullptr;
  }
#endif

  void set_value(Metadata* value) {
    _value = value;
  }

#ifdef METADATA_TRACK_NAMES
  const char* name() { return _name; }
  void set_name(const char* name) {
    if (_name != nullptr) {
      os::free((void*) _name);
      _name = nullptr;
    }
    if (name != nullptr) {
      _name = os::strdup(name);
    }
  }
#endif
};

typedef struct _jmetadata HandleRecord;
typedef struct _jmetadata *jmetadata;
class MetadataHandles;

class MetadataHandleBlock : public CHeapObj<mtJVMCI> {
  friend class MetadataHandles;
 private:
  enum SomeConstants {
    block_size_in_handles  = 32 // Number of handles per handle block
  };

  // Free handles always have their low bit set so those pointers can
  // be distinguished from handles which are in use.  The last handle
  // on the free list has a null pointer with the tag bit set, so it's
  // clear that the handle has been reclaimed.  The _free_list is
  // always a real pointer to a handle.

  HandleRecord    _handles[block_size_in_handles]; // The handles
  int             _top;                         // Index of next unused handle
  MetadataHandleBlock* _next;                   // Link to next block

  MetadataHandleBlock() {
    _top = 0;
    _next = nullptr;
#ifdef METADATA_TRACK_NAMES
    for (int i = 0; i < block_size_in_handles; i++) {
      _handles[i].initialize();
    }
#endif
  }

  const char* get_name(int index) {
#ifdef METADATA_TRACK_NAMES
    return _handles[index].name();
#else
    return "<missing>";
#endif
  }
};

// JVMCI maintains direct references to metadata. To make these references safe in the face of
// class redefinition, they are held in handles so they can be scanned during GC. They are
// managed in a cooperative way between the Java code and HotSpot. A handle is filled in and
// passed back to the Java code which is responsible for setting the handle to null when it
// is no longer in use. This is done by jdk.vm.ci.hotspot.HandleCleaner. The
// rebuild_free_list function notices when the handle is clear and reclaims it for re-use.
class MetadataHandles : public CHeapObj<mtJVMCI> {
 private:
  enum SomeConstants {
    ptr_tag = 1,
    ptr_mask = ~((intptr_t)ptr_tag)
  };

  MetadataHandleBlock*   _head; // First block
  MetadataHandleBlock*   _last; // Last block in use
  intptr_t          _free_list; // Handle free list
  int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
  int              _num_blocks; // Number of blocks
  int             _num_handles;
  int        _num_free_handles;

  HandleRecord* get_free_handle() {
    HandleRecord* handle = (HandleRecord*) (_free_list & ptr_mask);
    _free_list = (ptr_mask & (intptr_t) (handle->value()));
    assert(_free_list != ptr_tag, "should be null");
    _num_free_handles--;
    return handle;
  }

  HandleRecord* get_handle() {
    assert(_last != nullptr, "sanity");
    // Try last block
    if (_last->_top < MetadataHandleBlock::block_size_in_handles) {
      _num_handles++;
      return &(_last->_handles)[_last->_top++];
    } else if (_free_list != 0) {
      // Try free list
      return get_free_handle();
    }
    return nullptr;
  }

  void rebuild_free_list();

  jmetadata allocate_metadata_handle(Metadata* metadata);

 public:
  MetadataHandles() {
    _head = nullptr;
    _last = nullptr;
    _free_list = 0;
    _allocate_before_rebuild = 0;
    _num_blocks = 0;
    _num_handles = 0;
    _num_free_handles = 0;
  }

  int num_handles() const { return _num_handles; }
  int num_free_handles() const { return _num_free_handles; }
  int num_blocks() const { return _num_blocks; }

  jmetadata allocate_handle(const methodHandle& handle)       { return allocate_metadata_handle(handle()); }
  jmetadata allocate_handle(const constantPoolHandle& handle) { return allocate_metadata_handle(handle()); }

  // Adds `handle` to the free list
  void chain_free_list(HandleRecord* handle) {
    handle->set_value((Metadata*) (ptr_tag | _free_list));
#ifdef METADATA_TRACK_NAMES
    handle->set_name(nullptr);
#endif
    _free_list = (intptr_t) handle;
    _num_free_handles++;
  }

  // Clears all handles without releasing any handle memory.
  void clear();

  void metadata_do(void f(Metadata*));

  void do_unloading();
};

#endif // SHARE_JVMCI_METADATAHANDLES_HPP
