/*
 * Copyright (c) 2024, 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/aotClassInitializer.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/cdsConfig.hpp"
#include "cds/heapShared.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionaryShared.hpp"
#include "classfile/vmSymbols.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"

DEBUG_ONLY(InstanceKlass* _aot_init_class = nullptr;)

// Detector for class names we wish to handle specially.
// It is either an exact string match or a string prefix match.
class AOTClassInitializer::AllowedSpec {
  const char* _class_name;
  bool _is_prefix;
  int _len;
public:
  AllowedSpec(const char* class_name, bool is_prefix = false)
    : _class_name(class_name), _is_prefix(is_prefix)
  {
    _len = (class_name == nullptr) ? 0 : (int)strlen(class_name);
  }
  const char* class_name() { return _class_name; }

  bool matches(Symbol* name, int len) {
    assert(_class_name != nullptr, "caller resp.");
    if (_is_prefix) {
      return len >= _len && name->starts_with(_class_name);
    } else {
      return len == _len && name->equals(_class_name);
    }
  }
};


// Tell if ik has a name that matches one of the given specs.
bool AOTClassInitializer::is_allowed(AllowedSpec* specs, InstanceKlass* ik) {
  Symbol* name = ik->name();
  int len = name->utf8_length();
  for (AllowedSpec* s = specs; s->class_name() != nullptr; s++) {
    if (s->matches(name, len)) {
      // If a type is included in the tables inside can_archive_initialized_mirror(), we require that
      //   - all super classes must be included
      //   - all super interfaces that have <clinit> must be included.
      // This ensures that in the production run, we don't run the <clinit> of a supertype but skips
      // ik's <clinit>.
      if (ik->java_super() != nullptr) {
        DEBUG_ONLY(ResourceMark rm);
        assert(AOTClassInitializer::can_archive_initialized_mirror(ik->java_super()),
               "super class %s of %s must be aot-initialized", ik->java_super()->external_name(),
               ik->external_name());
      }

      Array<InstanceKlass*>* interfaces = ik->local_interfaces();
      int len = interfaces->length();
      for (int i = 0; i < len; i++) {
        InstanceKlass* intf = interfaces->at(i);
        if (intf->class_initializer() != nullptr) {
          assert(AOTClassInitializer::can_archive_initialized_mirror(intf),
                 "super interface %s (which has <clinit>) of %s must be aot-initialized", intf->external_name(),
                 ik->external_name());
        }
      }

      return true;
    }
  }
  return false;
}


bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
  assert(!ArchiveBuilder::is_active() || !ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass");
  if (!CDSConfig::is_initing_classes_at_dump_time()) {
    return false;
  }

  if (!ik->is_initialized() && !ik->is_being_initialized()) {
    return false;
  }

  // About "static field that may hold a different value" errors:
  //
  // Automatic selection for aot-inited classes
  // ==========================================
  //
  // When CDSConfig::is_initing_classes_at_dump_time is enabled,
  // AOTArtifactFinder::find_artifacts() finds the classes of all
  // heap objects that are reachable from HeapShared::_run_time_special_subgraph,
  // and mark these classes as aot-inited. This preserves the initialized
  // mirrors of these classes, and their <clinit> methods are NOT executed
  // at runtime. See aotArtifactFinder.hpp for more info.
  //
  // For example, with -XX:+AOTInvokeDynamicLinking, _run_time_special_subgraph
  // will contain some DirectMethodHandle objects. As a result, the DirectMethodHandle
  // class is automatically marked as aot-inited.
  //
  // When a class is aot-inited, its static fields are already set up
  // by executing the <clinit> method at AOT assembly time.  Later on
  // in the production run, when the class would normally be
  // initialized, the VM performs guarding and synchronization as if
  // it were going to run the <clinit> again, but instead it simply
  // observes that that class was aot-inited.  The VM assumes that, if
  // it were to run <clinit> again, it would get a semantically
  // equivalent set of final field values, so it just adopts the
  // existing field values (from AOT assembly) and skips the call to
  // <clinit>.  There may at that point be fixups performed by ad hoc
  // code, if the VM recognizes a request in the library.
  //
  // It is true that this is not generally correct for all possible
  // Java code.  A <clinit> method might have a side effect beyond
  // initializing the static fields.  It might send an email somewhere
  // noting the current time of day.  In that case, such an email
  // would have been sent during the AOT assembly phase, and the email
  // would NOT be sent again during production.  This is clearly NOT
  // what a user would want, if this were a general purpose facility.
  // But in fact it is only for certain well-behaved classes, which
  // are known NOT to have such side effects.  We know this because
  // the optimization (of skipping <clinit> for aot-init classes) is
  // only applied to classes fully defined by the JDK.
  //
  // (A day may come when we figure out how to gracefully extend this
  // optimization to untrusted third parties, but it is not this day.)
  //
  // Manual selection
  // ================
  //
  // There are important cases where one aot-init class has a side
  // effect on another aot-class, a side effect which is not captured
  // in any static field value in either class.  The simplest example
  // is class A forces the initialization of class B.  In that case,
  // we need to aot-init either both classes or neither.  From looking
  // at the JDK state after AOT assembly is done, it is hard to tell
  // that A "touched" B and B might escape our notice.  Another common
  // example is A copying a field value from B.  We don't know where A
  // got the value, but it would be wrong to re-initialize B at
  // startup, while keeping the snapshot of the old B value in A.  In
  // general, if we aot-init A, we need to aot-init every class B that
  // somehow contributed to A's initial state, and every class C that
  // was somehow side-effected by A's initialization.  We say that the
  // aot-init of A is "init-coupled" to those of B and C.
  //
  // So there are init-coupled classes that cannot be automatically discovered. For
  // example, DirectMethodHandle::IMPL_NAMES points to MethodHandles::IMPL_NAMES,
  // but the MethodHandles class is not automatically marked because there are
  // no archived instances of the MethodHandles type.
  //
  // If we aot-initialize DirectMethodHandle, but allow MethodHandles to be
  // initialized at runtime, MethodHandles::IMPL_NAMES will get a different
  // value than DirectMethodHandle::IMPL_NAMES. This *may or may not* be a problem,
  // but to ensure compatibility, we should try to preserve the identity equality
  // of these two fields.
  //
  // To do that, we add MethodHandles to the indy_specs[] table below.
  //
  // Luckily we do not need to be all-knowing in order to choose which
  // items to add to that table.  We have tools to help detect couplings.
  //
  // Automatic validation
  // ====================
  //
  // CDSHeapVerifier is used to detect potential problems with identity equality.
  //
  // A class B is assumed to be init-coupled to some aot-init class if
  // B has a field which points to a live object X in the AOT heap.
  // The live object X was created by some other class A which somehow
  // used B's reference to X, perhaps with the help of an intermediate
  // class Z.  Or, B pulled the reference to X from some other class
  // Y, and B obtained that reference from Y (or an intermediate Z).
  // It is not certain how X got into the heap, nor whether B
  // contributed it, but it is a good heuristic that B is init-coupled
  // to X's class or some other aot-init class.  In any case, B should
  // be made an aot-init class as well, unless a manual inspection
  // shows that would be a problem.  If there is a problem, then the
  // JDK code for B and/or X probably needs refactoring.  If there is
  // no problem, we add B to the list.  Typically the same scan will
  // find any other accomplices Y, Z, etc.  One failure would be a
  // class Q whose only initialization action is to scribble a special
  // value into B, from which the value X is derived and then makes
  // its way into the heap.  In that case, the heuristic does not
  // identify Q.  It is (currently) a human responsibility, of JDK
  // engineers, not to write such dirty JDK code, or to repair it if
  // it crops up.  Eventually we may have tools, or even a user mode
  // with design rules and checks, that will vet our code base more
  // automatically.
  //
  // To see how the tool detects the problem with MethodHandles::IMPL_NAMES:
  //
  // - Comment out all the lines in indy_specs[] except the {nullptr} line.
  // - Rebuild the JDK
  //
  // Then run the following:
  //    java -XX:AOTMode=record -XX:AOTConfiguration=jc.aotconfig com.sun.tools.javac.Main
  //    java -XX:AOTMode=create -Xlog:aot -XX:AOTCache=jc.aot -XX:AOTConfiguration=jc.aotconfig
  //
  // You will see an error like this:
  //
  // Archive heap points to a static field that may hold a different value at runtime:
  // Field: java/lang/invoke/MethodHandles::IMPL_NAMES
  // Value: java.lang.invoke.MemberName$Factory
  // {0x000000060e906ae8} - klass: 'java/lang/invoke/MemberName$Factory' - flags:
  //
  //  - ---- fields (total size 2 words):
  // --- trace begin ---
  // [ 0] {0x000000060e8deeb0} java.lang.Class (java.lang.invoke.DirectMethodHandle::IMPL_NAMES)
  // [ 1] {0x000000060e906ae8} java.lang.invoke.MemberName$Factory
  // --- trace end ---
  //
  // Trouble-shooting
  // ================
  //
  // If you see a "static field that may hold a different value" error, it's probably
  // because you've made some changes in the JDK core libraries (most likely
  // java.lang.invoke).
  //
  //  - Did you add a new static field to a class that could be referenced by
  //    cached object instances of MethodType, MethodHandle, etc? You may need
  //    to add that class to indy_specs[].
  //  - Did you modify the <clinit> of the classes in java.lang.invoke such that
  //    a static field now points to an object that should not be cached (e.g.,
  //    a native resource such as a file descriptior, or a Thread)?
  //
  // Note that these potential problems only occur when one class gets
  // the aot-init treatment, AND another class is init-coupled to it,
  // AND the coupling is not detected.  Currently there are a number
  // classes that get the aot-init treatment, in java.lang.invoke
  // because of invokedynamic.  They are few enough for now to be
  // manually tracked.  There may be more in the future.

  // IS_PREFIX means that we match all class names that start with a
  // prefix.  Otherwise, it is an exact match, of just one class name.
  const bool IS_PREFIX = true;

  {
    static AllowedSpec specs[] = {
      // everybody's favorite super
      {"java/lang/Object"},

      {nullptr}
    };
    if (is_allowed(specs, ik)) {
      return true;
    }
  }

  if (CDSConfig::is_dumping_method_handles()) {
    // This table was created with the help of CDSHeapVerifier.
    // Also, some $Holder classes are needed. E.g., Invokers.<clinit> explicitly
    // initializes Invokers$Holder. Since Invokers.<clinit> won't be executed
    // at runtime, we need to make sure Invokers$Holder is also aot-inited.
    //
    // We hope we can reduce the size of this list over time, and move
    // the responsibility for identifying such classes into the JDK
    // code itself.  See tracking RFE JDK-8342481.
    static AllowedSpec indy_specs[] = {
      {"java/lang/constant/ConstantDescs"},
      {"java/lang/constant/DynamicConstantDesc"},
      {"java/lang/invoke/BoundMethodHandle"},
      {"java/lang/invoke/BoundMethodHandle$Specializer"},
      {"java/lang/invoke/BoundMethodHandle$Species_", IS_PREFIX},
      {"java/lang/invoke/ClassSpecializer"},
      {"java/lang/invoke/ClassSpecializer$", IS_PREFIX},
      {"java/lang/invoke/DelegatingMethodHandle"},
      {"java/lang/invoke/DelegatingMethodHandle$Holder"},     // UNSAFE.ensureClassInitialized()
      {"java/lang/invoke/DirectMethodHandle"},
      {"java/lang/invoke/DirectMethodHandle$Constructor"},
      {"java/lang/invoke/DirectMethodHandle$Holder"},         // UNSAFE.ensureClassInitialized()
      {"java/lang/invoke/Invokers"},
      {"java/lang/invoke/Invokers$Holder"},                   // UNSAFE.ensureClassInitialized()
      {"java/lang/invoke/LambdaForm"},
      {"java/lang/invoke/LambdaForm$Holder"},                 // UNSAFE.ensureClassInitialized()
      {"java/lang/invoke/LambdaForm$NamedFunction"},
      {"java/lang/invoke/LambdaMetafactory"},
      {"java/lang/invoke/MethodHandle"},
      {"java/lang/invoke/MethodHandles"},
      {"java/lang/invoke/SimpleMethodHandle"},
      {"java/lang/invoke/StringConcatFactory"},
      {"java/lang/invoke/VarHandleGuards"},
      {"java/util/Collections"},
      {"java/util/stream/Collectors"},
      {"jdk/internal/constant/ConstantUtils"},
      {"jdk/internal/constant/PrimitiveClassDescImpl"},
      {"jdk/internal/constant/ReferenceClassDescImpl"},

    // Can't include this, as it will pull in MethodHandleStatics which has many environment
    // dependencies (on system properties, etc).
    // MethodHandleStatics is an example of a class that must NOT get the aot-init treatment,
    // because of its strong reliance on (a) final fields which are (b) environmentally determined.
    //{"java/lang/invoke/InvokerBytecodeGenerator"},

      {nullptr}
    };
    if (is_allowed(indy_specs, ik)) {
      return true;
    }

    if (ik->name()->starts_with("java/lang/invoke/MethodHandleImpl")) {
      return true;
    }
  }

#ifdef ASSERT
  if (ik == _aot_init_class) {
    return true;
  }
#endif

  return false;
}

// TODO: currently we have a hard-coded list. We should turn this into
// an annotation: @jdk.internal.vm.annotation.RuntimeSetupRequired
// See JDK-8342481.
bool AOTClassInitializer::is_runtime_setup_required(InstanceKlass* ik) {
  return ik == vmClasses::Class_klass() ||
         ik == vmClasses::internal_Unsafe_klass() ||
         ik == vmClasses::ConcurrentHashMap_klass() ||
         ik == vmClasses::MethodHandleImpl_klass() ||
         ik == vmClasses::Reference_klass();
}

void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
  assert(ik->has_aot_initialized_mirror(), "sanity");
  if (ik->is_runtime_setup_required()) {
    if (log_is_enabled(Info, aot, init)) {
      ResourceMark rm;
      log_info(aot, init)("Calling %s::runtimeSetup()", ik->external_name());
    }
    JavaValue result(T_VOID);
    JavaCalls::call_static(&result, ik,
                           vmSymbols::runtimeSetup(),
                           vmSymbols::void_method_signature(), current);
    if (current->has_pending_exception()) {
      // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
      // exception would cause ik to be in an error state.
      AOTLinkedClassBulkLoader::exit_on_exception(current);
    }
  }
}

#ifdef ASSERT
void AOTClassInitializer::init_test_class(TRAPS) {
  // -XX:AOTInitTestClass is used in regression tests for adding additional AOT-initialized classes
  // and heap objects into the AOT cache. The tests must be carefully written to avoid including
  // any classes that cannot be AOT-initialized.
  //
  // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into
  // the AOT cache. Therefore, this option is NOT available in product JVM.
  if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time()) {
    log_info(aot)("Debug build only: force initialization of AOTInitTestClass %s", AOTInitTestClass);
    TempNewSymbol class_name = SymbolTable::new_symbol(AOTInitTestClass);
    Handle app_loader(THREAD, SystemDictionary::java_system_loader());
    Klass* k = SystemDictionary::resolve_or_null(class_name, app_loader, CHECK);
    if (k == nullptr) {
      vm_exit_during_initialization("AOTInitTestClass not found", AOTInitTestClass);
    }
    if (!k->is_instance_klass()) {
      vm_exit_during_initialization("Invalid name for AOTInitTestClass", AOTInitTestClass);
    }

    _aot_init_class = InstanceKlass::cast(k);
    _aot_init_class->initialize(CHECK);
  }
}

bool AOTClassInitializer::has_test_class() {
  return _aot_init_class != nullptr;
}
#endif
