/*
 * Copyright (c) 2021, 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.
 *
 */

#include "cds/aotLinkedClassBulkLoader.hpp"
#include "cds/archiveHeapLoader.hpp"
#include "cds/cdsConfig.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/metaspaceClosure.hpp"
#include "memory/universe.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp"
#include "oops/instanceStackChunkKlass.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/globals.hpp"

InstanceKlass* vmClasses::_klasses[static_cast<int>(vmClassID::LIMIT)]
                                                 =  { nullptr /*, nullptr...*/ };
InstanceKlass* vmClasses::_box_klasses[T_VOID+1] =  { nullptr /*, nullptr...*/ };

bool vmClasses::is_loaded(InstanceKlass* klass) {
  return klass != nullptr && klass->is_loaded();
}

// Compact table of the vmSymbolIDs of all the VM classes (stored as short to save space)
static const short vm_class_name_ids[] = {
  #define VM_CLASS_NAME(name, symbol) ((short)VM_SYMBOL_ENUM_NAME(symbol)),
  VM_CLASSES_DO(VM_CLASS_NAME)
  #undef VM_CLASS_NAME
  0
};


#ifdef ASSERT
bool vmClasses::contain(Symbol* class_name) {
  int sid;
  for (int i = 0; (sid = vm_class_name_ids[i]) != 0; i++) {
    Symbol* symbol = vmSymbols::symbol_at(vmSymbols::as_SID(sid));
    if (class_name == symbol) {
      return true;
    }
  }
  return false;
}

bool vmClasses::contain(Klass* k) {
  return contain(k->name());
}
#endif

bool vmClasses::resolve(vmClassID id, TRAPS) {
  InstanceKlass** klassp = &_klasses[as_int(id)];

#if INCLUDE_CDS
  if (CDSConfig::is_using_archive() && !JvmtiExport::should_post_class_prepare()) {
    InstanceKlass* k = *klassp;
    assert(k->defined_by_boot_loader(), "must be");

    ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
    resolve_shared_class(k, loader_data, Handle(), CHECK_false);
    return true;
  }
#endif // INCLUDE_CDS

  if (!is_loaded(*klassp)) {
    int sid = vm_class_name_ids[as_int(id)];
    Symbol* symbol = vmSymbols::symbol_at(vmSymbols::as_SID(sid));
    Klass* k = SystemDictionary::resolve_or_fail(symbol, true, CHECK_false);
    (*klassp) = InstanceKlass::cast(k);
  }
  return ((*klassp) != nullptr);
}

void vmClasses::resolve_until(vmClassID limit_id, vmClassID &start_id, TRAPS) {
  assert((int)start_id <= (int)limit_id, "IDs are out of order!");
  for (auto id : EnumRange<vmClassID>{start_id, limit_id}) { // (inclusive start, exclusive end)
    resolve(id, CHECK);
  }

  // move the starting value forward to the limit:
  start_id = limit_id;
}

void vmClasses::resolve_all(TRAPS) {
  assert(!Object_klass_loaded(), "well-known classes should only be initialized once");

  // Create the ModuleEntry for java.base.  This call needs to be done here,
  // after vmSymbols::initialize() is called but before any classes are pre-loaded.
  ClassLoader::classLoader_init2(THREAD);

  // Preload commonly used klasses
  vmClassID scan = vmClassID::FIRST;
  // first do Object, then String, Class
  resolve_through(VM_CLASS_ID(Object_klass), scan, CHECK);
  CollectedHeap::set_filler_object_klass(vmClasses::Object_klass());
#if INCLUDE_CDS
  if (CDSConfig::is_using_archive()) {
    // It's unsafe to access the archived heap regions before they
    // are fixed up, so we must do the fixup as early as possible
    // before the archived java objects are accessed by functions
    // such as java_lang_Class::restore_archived_mirror and
    // ConstantPool::restore_unshareable_info (restores the archived
    // resolved_references array object).
    //
    // ArchiveHeapLoader::fixup_regions fills the empty
    // spaces in the archived heap regions and may use
    // vmClasses::Object_klass(), so we can do this only after
    // Object_klass is resolved. See the above resolve_through()
    // call. No mirror objects are accessed/restored in the above call.
    // Mirrors are restored after java.lang.Class is loaded.
    ArchiveHeapLoader::fixup_region();

    // Initialize the constant pool for the Object_class
    assert(Object_klass()->is_shared(), "must be");
    Object_klass()->constants()->restore_unshareable_info(CHECK);
    resolve_through(VM_CLASS_ID(Class_klass), scan, CHECK);
  } else
#endif
  {
    resolve_through(VM_CLASS_ID(Class_klass), scan, CHECK);
  }

  assert(vmClasses::Object_klass() != nullptr, "well-known classes should now be initialized");

  java_lang_Object::register_natives(CHECK);

  // Calculate offsets for String and Class classes since they are loaded and
  // can be used after this point. These are no-op when CDS is enabled.
  java_lang_String::compute_offsets();
  java_lang_Class::compute_offsets();

  // Fixup mirrors for classes loaded before java.lang.Class.
  Universe::initialize_basic_type_mirrors(CHECK);
  Universe::fixup_mirrors(CHECK);

  if (CDSConfig::is_using_archive()) {
    // These should already have been initialized during CDS dump.
    assert(vmClasses::Reference_klass()->reference_type() == REF_NONE, "sanity");
    assert(vmClasses::SoftReference_klass()->reference_type() == REF_SOFT, "sanity");
    assert(vmClasses::WeakReference_klass()->reference_type() == REF_WEAK, "sanity");
    assert(vmClasses::FinalReference_klass()->reference_type() == REF_FINAL, "sanity");
    assert(vmClasses::PhantomReference_klass()->reference_type() == REF_PHANTOM, "sanity");
  } else {
    // If CDS is not enabled, the references classes must be initialized in
    // this order before the rest of the vmClasses can be resolved.
    resolve_through(VM_CLASS_ID(Reference_klass), scan, CHECK);

    // The offsets for jlr.Reference must be computed before
    // InstanceRefKlass::update_nonstatic_oop_maps is called. That function uses
    // the offsets to remove the referent and discovered fields from the oop maps,
    // as they are treated in a special way by the GC. Removing these oops from the
    // oop maps must be done before the usual subclasses of jlr.Reference are loaded.
    java_lang_ref_Reference::compute_offsets();

    // Preload ref klasses and set reference types
    InstanceRefKlass::update_nonstatic_oop_maps(vmClasses::Reference_klass());

    resolve_through(VM_CLASS_ID(PhantomReference_klass), scan, CHECK);
  }

  resolve_until(vmClassID::LIMIT, scan, CHECK);

  CollectedHeap::set_filler_object_klass(vmClasses::FillerObject_klass());

  _box_klasses[T_BOOLEAN] = vmClasses::Boolean_klass();
  _box_klasses[T_CHAR]    = vmClasses::Character_klass();
  _box_klasses[T_FLOAT]   = vmClasses::Float_klass();
  _box_klasses[T_DOUBLE]  = vmClasses::Double_klass();
  _box_klasses[T_BYTE]    = vmClasses::Byte_klass();
  _box_klasses[T_SHORT]   = vmClasses::Short_klass();
  _box_klasses[T_INT]     = vmClasses::Integer_klass();
  _box_klasses[T_LONG]    = vmClasses::Long_klass();

#ifdef ASSERT
  if (CDSConfig::is_using_archive()) {
    JVMTI_ONLY(assert(JvmtiExport::is_early_phase(),
                      "All well known classes must be resolved in JVMTI early phase"));
    for (auto id : EnumRange<vmClassID>{}) {
      InstanceKlass* k = _klasses[as_int(id)];
      assert(k->is_shared(), "must not be replaced by JVMTI class file load hook");
    }
  }
#endif

  InstanceStackChunkKlass::init_offset_of_stack();
#if INCLUDE_CDS
  if (CDSConfig::is_using_aot_linked_classes()) {
    AOTLinkedClassBulkLoader::load_javabase_classes(THREAD);
  }
#endif
}

#if INCLUDE_CDS

void vmClasses::resolve_shared_class(InstanceKlass* klass, ClassLoaderData* loader_data, Handle domain, TRAPS) {
  assert(!Universe::is_fully_initialized(), "We can make short cuts only during VM initialization");
  assert(klass->is_shared(), "Must be shared class");
  if (klass->class_loader_data() != nullptr) {
    return;
  }

  // add super and interfaces first
  Klass* super = klass->super();
  if (super != nullptr && super->class_loader_data() == nullptr) {
    assert(super->is_instance_klass(), "Super should be instance klass");
    resolve_shared_class(InstanceKlass::cast(super), loader_data, domain, CHECK);
  }

  Array<InstanceKlass*>* ifs = klass->local_interfaces();
  for (int i = 0; i < ifs->length(); i++) {
    InstanceKlass* ik = ifs->at(i);
    if (ik->class_loader_data()  == nullptr) {
      resolve_shared_class(ik, loader_data, domain, CHECK);
    }
  }

  klass->restore_unshareable_info(loader_data, domain, nullptr, THREAD);
  SystemDictionary::load_shared_class_misc(klass, loader_data);
  Dictionary* dictionary = loader_data->dictionary();
  dictionary->add_klass(THREAD, klass->name(), klass);
  klass->add_to_hierarchy(THREAD);
  assert(klass->is_loaded(), "Must be in at least loaded state");
}

#endif // INCLUDE_CDS

// Tells if a given klass is a box (wrapper class, such as java.lang.Integer).
// If so, returns the basic type it holds.  If not, returns T_OBJECT.
BasicType vmClasses::box_klass_type(Klass* k) {
  assert(k != nullptr, "");
  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
    if (_box_klasses[i] == k)
      return (BasicType)i;
  }
  return T_OBJECT;
}
