/*
 * Copyright (c) 2014, 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_GC_SHARED_STRINGDEDUP_STRINGDEDUPTABLE_HPP
#define SHARE_GC_SHARED_STRINGDEDUP_STRINGDEDUPTABLE_HPP

#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shared/stringdedup/stringDedupStat.hpp"
#include "memory/allStatic.hpp"
#include "oops/typeArrayOop.hpp"
#include "oops/weakHandle.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"

class OopStorage;

// Provides deduplication.  This class keeps track of all the unique byte
// arrays used by deduplicated String objects.
//
// The arrays are in a hashtable, hashed using the bytes in the array.  The
// references to the arrays by the hashtable are weak, allowing arrays that
// become unreachable to be collected and their entries pruned from the
// table.  The hashtable is dynamically resized to accommodate the current
// number of hashtable entries.  There are several command line options
// controlling the growth or shrinkage of the hashtable.
//
// Operations on the table are not thread-safe.  Only the deduplication
// thread calls most of the operations on the table.  The only exception is
// the GC dead object count notification and the management of its state.
//
// The table supports resizing and removal of entries for byte arrays that
// have become unreferenced.  These operations are performed by the
// deduplication thread, in a series of small incremental steps.  This
// prevents these potentially long running operations from long blockage of
// safepoints or concurrent deduplication requests from the StringTable.
//
// As a space optimization, when shared StringTable entries exist the shared
// part of the StringTable is also used as a source for byte arrays.  This
// permits deduplication of strings against those shared entries without
// recording them in this table too.
class StringDedup::Table : AllStatic {
private:
  class Bucket;
  class CleanupState;
  class Resizer;
  class Cleaner;
  enum class DeadState;

  // Values in the table are weak references to jbyte[] Java objects.  The
  // String's coder isn't recorded, even though it affects how String access
  // would interpret that array.  For the purposes of deduplication we don't
  // care about that distinction; two Strings with equivalent arrays but
  // different coders can be deduplicated to share a single array.  We also
  // can't depend on the coder value being correct here, since GC requests
  // can provide the deduplication thread with access to a String that is
  // incompletely constructed; the value could be set before the coder.
  using TableValue = WeakHandle;

  // Weak storage for the string data in the table.
  static OopStorage* _table_storage;
  static Bucket* _buckets;
  static size_t _number_of_buckets;
  static size_t _number_of_entries;
  static size_t _grow_threshold;
  static CleanupState* _cleanup_state;
  static bool _need_bucket_shrinking;
  // These are always written while holding StringDedup_lock, but may be
  // read by the dedup thread without holding the lock lock.
  static volatile size_t _dead_count;
  static volatile DeadState _dead_state;

  static uint compute_hash(typeArrayOop obj);
  static size_t hash_to_index(uint hash_code);
  static void add(TableValue tv, uint hash_code);
  static TableValue find(typeArrayOop obj, uint hash_code);
  static void install(typeArrayOop obj, uint hash_code);
  static bool deduplicate_if_permitted(oop java_string, typeArrayOop value);
  static bool try_deduplicate_shared(oop java_string);
  static bool try_deduplicate_found_shared(oop java_string, oop found);
  static Bucket* make_buckets(size_t number_of_buckets, size_t reserve = 0);
  static void free_buckets(Bucket* buckets, size_t number_of_buckets);

  static bool start_resizer(bool grow_only, size_t number_of_entries);
  static bool start_cleaner(size_t number_of_entries, size_t dead_count);

  static void num_dead_callback(size_t num_dead);
  static bool is_dead_count_good_acquire();
  static void set_dead_state_cleaning();

public:
  static void initialize_storage();
  static void initialize();

  // Deduplicate java_string.  If the table already contains the string's
  // data array, replace the string's data array with the one in the table.
  // Otherwise, add the string's data array to the table.
  static void deduplicate(oop java_string);

  // Returns true if table needs to grow.
  static bool is_grow_needed();

  // Returns true if there are enough dead entries to need cleanup.
  static bool is_dead_entry_removal_needed();

  // If cleanup (resizing or removing dead entries) is needed or force
  // is true, setup cleanup state and return true.  If result is true,
  // the caller must eventually call cleanup_end.
  // precondition: no cleanup is in progress.
  static bool cleanup_start_if_needed(bool grow_only, bool force);

  // Perform some cleanup work.  Returns true if any progress was made,
  // false if there is no further work to do.
  // precondition: a cleanup is in progress.
  static bool cleanup_step();

  // Record the cleanup complete and cleanup state.
  // precondition: a cleanup is in progress.
  static void cleanup_end();

  static void verify();
  static void log_statistics();
};

#endif // SHARE_GC_SHARED_STRINGDEDUP_STRINGDEDUPTABLE_HPP
