/*
 * Copyright (c) 2019, 2025, 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_OOPS_COMPRESSEDKLASS_HPP
#define SHARE_OOPS_COMPRESSEDKLASS_HPP

#include "memory/allStatic.hpp"
#include "utilities/align.hpp"
#include "utilities/globalDefinitions.hpp"

class outputStream;
class Klass;

// Narrow Klass Encoding
//
// Klass Range:
//  a contiguous memory range into which we place Klass that should be encodable. Not every Klass
//  needs to be encodable. There is only one such memory range.
//  If CDS is disabled, this Klass Range is the same as the metaspace class space. If CDS is enabled, the
//  Klass Range contains both CDS and class space adjacent to each other (with a potential small
//  unused alignment gap between them).
//
// Encoding Range:
//  This is the range covered by the current encoding scheme. The encoding scheme is defined by
//  the encoding base, encoding shift and (implicitly) the bit size of the narrowKlass. The
//  Encoding Range is:
//   [ <encoding base> ... <encoding base> + (1 << (<narrowKlass-bitsize> + <shift>) )
//
// Note that while the Klass Range must be contained within the Encoding Range, the Encoding Range
// is typically a lot larger than the Klass Range:
//  - the encoding base can start before the Klass Range start (specifically, it can start at 0 for
//    zero-based encoding)
//  - the end of the Encoding Range usually extends far beyond the end of the Klass Range.
//
//
// Examples:
//
// "unscaled" (zero-based zero-shift) encoding, CDS off, class space of 1G starts at 0x4B00_0000:
// - Encoding Range: [0             .. 0x1_0000_0000 ) (4 GB)
// - Klass Range:    [0x4B00_0000   .. 0x  8B00_0000 ) (1 GB)
//
//
// _base        _klass_range_start              _klass_range_end             encoding end
//   |                |//////////////////////////////|                             |
//   |   ...          |///////1gb class space////////|               ...           |
//   |                |//////////////////////////////|                             |
//  0x0         0x4B00_0000                   0x8B00_0000                    0x1_0000_0000
//
//
//
// "zero-based" (but scaled) encoding, shift=3, CDS off, 1G Class space at 0x7_C000_0000 (31GB):
// - Encoding Range: [0             .. 0x8_0000_0000 ) (32 GB)
// - Klass Range:    [0x7_C000_0000 .. 0x8_0000_0000 ) (1 GB)
//
//                                                                  encoding end
// _base                            _klass_range_start              _klass_range_end
//   |                                   |//////////////////////////////|
//   |   ...                             |///////1gb class space////////|
//   |                                   |//////////////////////////////|
//  0x0                            0x7_C000_0000                  0x8_0000_0000
//
//
// CDS enabled, 128MB CDS region starts 0x8_0000_0000, followed by a 1GB class space. Encoding
// base will point to CDS region start, shift=0:
// - Encoding Range: [0x8_0000_0000 .. 0x9_0000_0000 ) (4 GB)
// - Klass Range:    [0x8_0000_0000 .. 0x8_4800_0000 ) (128 MB + 1 GB)
//
//  _base
// _klass_range_start                   _klass_range_end                        encoding end
//   |//////////|///////////////////////////|                                         |
//   |///CDS////|////1gb class space////////|            ...    ...                   |
//   |//////////|///////////////////////////|                                         |
//   |                                      |                                         |
// 0x8_0000_0000                      0x8_4800_0000                            0x9_0000_0000
//

// If compressed klass pointers then use narrowKlass.
typedef juint  narrowKlass;

// For UseCompressedClassPointers.
class CompressedKlassPointers : public AllStatic {
  friend class VMStructs;
  friend class ArchiveBuilder;

  // We use a different narrow Klass pointer geometry depending on
  // whether we run in standard mode or in compact-object-header-mode.

  // Narrow klass pointer bits for an unshifted narrow Klass pointer.
  static constexpr int narrow_klass_pointer_bits_noncoh = 32;
  static constexpr int narrow_klass_pointer_bits_coh = 22;

  // Bit size of a narrowKlass
  static int _narrow_klass_pointer_bits;

  // The maximum shift values we can use depending on UseCompactObjectHeaders
  static constexpr int max_shift_noncoh = 3;
  static constexpr int max_shift_coh = 10;

  // Maximum shift usable
  static int _max_shift;

  // Encoding Base, Encoding Shift
  static address _base;
  static int _shift;

  // Start and end of the Klass Range.
  // Note: guaranteed to be aligned to 1<<shift (klass_alignment_in_bytes)
  static address _klass_range_start;
  static address _klass_range_end;

  // Values for the lowest (inclusive) and highest (inclusive) narrow Klass ID, given the
  // current Klass Range and encoding settings.
  static narrowKlass _lowest_valid_narrow_klass_id;
  static narrowKlass _highest_valid_narrow_klass_id;

  // Protection zone size (0 if not set up)
  static size_t _protection_zone_size;

  // Helper function for common cases.
  static char* reserve_address_space_X(uintptr_t from, uintptr_t to, size_t size, size_t alignment, bool aslr);
  static char* reserve_address_space_below_4G(size_t size, bool aslr);
  static char* reserve_address_space_for_unscaled_encoding(size_t size, bool aslr);
  static char* reserve_address_space_for_zerobased_encoding(size_t size, bool aslr);
  static char* reserve_address_space_for_16bit_move(size_t size, bool aslr);
  static void calc_lowest_highest_narrow_klass_id();

#ifdef ASSERT
  static void sanity_check_after_initialization();
#endif // ASSERT

  template <typename T>
  static inline void check_init(T var) {
    assert(var != (T)-1, "Not yet initialized");
  }

  static inline Klass* decode_not_null_without_asserts(narrowKlass v, address base, int shift);

public:

  // Initialization sequence:
  // 1) Parse arguments. The following arguments take a role:
  //      - UseCompressedClassPointers
  //      - UseCompactObjectHeaders
  //      - Xshare on off dump
  //      - CompressedClassSpaceSize
  // 2) call pre_initialize(): depending on UseCompactObjectHeaders, defines the limits of narrow Klass pointer
  //    geometry (how many bits, the max. possible shift)
  // 3) .. from here on, narrow_klass_pointer_bits() and max_shift() can be used
  // 4) call reserve_address_space_for_compressed_classes() either from CDS initialization or, if CDS is off,
  //    from metaspace initialization. Reserves space for class space + CDS, attempts to reserve such that
  //    we later can use a "good" encoding scheme. Reservation is highly CPU-specific.
  // 5) Initialize the narrow Klass encoding scheme by determining encoding base and shift:
  //   5a) if CDS=on: Calls initialize_for_given_encoding() with the reservation base from step (4) and the
  //       CDS-intrinsic setting for shift; here, we don't have any freedom to deviate from the base.
  //   5b) if CDS=off: Calls initialize() - here, we have more freedom and, if we want, can choose an encoding
  //       base that differs from the reservation base from step (4). That allows us, e.g., to later use
  //       zero-based encoding.
  // 6) ... from now on, we can use base() and shift().

  // Called right after argument parsing; defines narrow klass pointer geometry limits
  static void pre_initialize();

  // The number of bits a narrow Klass pointer has;
  static int narrow_klass_pointer_bits() { check_init(_narrow_klass_pointer_bits); return _narrow_klass_pointer_bits; }

  // The maximum possible shift; the actual shift employed later can be smaller (see initialize())
  static int max_shift()                 { check_init(_max_shift); return _max_shift; }

  // Returns the maximum encoding range, given the current geometry (narrow klass bit size and shift)
  static size_t max_encoding_range_size() { return nth_bit(narrow_klass_pointer_bits() + max_shift()); }

  // Returns the maximum allowed klass range size.
  static size_t max_klass_range_size();

  // Reserve a range of memory that is to contain Klass strucutures which are referenced by narrow Klass IDs.
  // If optimize_for_zero_base is true, the implementation will attempt to reserve optimized for zero-based encoding.
  static char* reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base);

  // Given a klass range [addr, addr+len) and a given encoding scheme, assert that this scheme covers the range, then
  // set this encoding scheme. Used by CDS at runtime to re-instate the scheme used to pre-compute klass ids for
  // archived heap objects. In this case, we don't have the freedom to choose base and shift; they are handed to
  // us from CDS.
  static void initialize_for_given_encoding(address addr, size_t len, address requested_base, int requested_shift);

  // Given an address range [addr, addr+len) which the encoding is supposed to
  //  cover, choose base, shift and range.
  //  The address range is the expected range of uncompressed Klass pointers we
  //  will encounter (and the implicit promise that there will be no Klass
  //  structures outside this range).
  static void initialize(address addr, size_t len);

  static void     print_mode(outputStream* st);

  // Can only be used after initialization
  static address  base()             { check_init(_base); return  _base; }
  static address  base_addr()        { return  (address)&_base; }
  static int      shift()            { check_init(_shift); return  _shift; }

  static address  klass_range_start()  { return  _klass_range_start; }
  static address  klass_range_end()    { return  _klass_range_end; }

  static inline address encoding_range_end();

  // Returns the alignment a Klass* is guaranteed to have.
  // Note: *Not* the same as 1 << shift ! Klass are always guaranteed to be at least 64-bit aligned,
  // so this will return 8 even if shift is 0.
  static int klass_alignment_in_bytes() { return nth_bit(MAX2(3, _shift)); }
  static int klass_alignment_in_words() { return klass_alignment_in_bytes() / BytesPerWord; }

  // Returns the highest possible narrowKlass value given the current Klass range
  static narrowKlass highest_valid_narrow_klass_id() { return _highest_valid_narrow_klass_id; }

  static bool is_null(Klass* v)      { return v == nullptr; }
  static bool is_null(narrowKlass v) { return v == 0; }

  // Versions without asserts
  static inline Klass* decode_not_null_without_asserts(narrowKlass v);
  static inline Klass* decode_without_asserts(narrowKlass v);
  static inline Klass* decode_not_null(narrowKlass v);
  static inline Klass* decode(narrowKlass v);

  static inline narrowKlass encode_not_null_without_asserts(Klass* k, address narrow_base, int shift);
  static inline narrowKlass encode_not_null(Klass* v);
  static inline narrowKlass encode(Klass* v);

#ifdef ASSERT
  // Given an address, check that it can be encoded with the current encoding
  inline static void check_encodable(const void* addr);
  // Given a narrow Klass ID, check that it is valid according to current encoding
  inline static void check_valid_narrow_klass_id(narrowKlass nk);
#endif

  // Returns whether the pointer is in the memory region used for encoding compressed
  // class pointers.  This includes CDS.
  static inline bool is_encodable(const void* addr) {
    // An address can only be encoded if:
    //
    // 1) the address lies within the klass range.
    // 2) It is suitably aligned to 2^encoding_shift. This only really matters for
    //    +UseCompactObjectHeaders, since the encoding shift can be large (max 10 bits -> 1KB).
    return (address)addr >= _klass_range_start && (address)addr < _klass_range_end &&
        is_aligned(addr, klass_alignment_in_bytes());
  }

  // Protect a zone a the start of the encoding range
  static void establish_protection_zone(address addr, size_t size);

  // Returns true if address points into protection zone (for error reporting)
  static bool is_in_protection_zone(address addr);

#if defined(AARCH64) && !defined(ZERO)
  // Check that with the given base, shift and range, aarch64 code can encode and decode the klass pointer.
  static bool check_klass_decode_mode(address base, int shift, const size_t range);
  // Called after initialization.
  static bool set_klass_decode_mode();
#else
  static bool check_klass_decode_mode(address base, int shift, const size_t range) { return true; }
  static bool set_klass_decode_mode() { return true; }
#endif
};

#endif // SHARE_OOPS_COMPRESSEDKLASS_HPP
