/*
 * Copyright (c) 1997, 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_CLASSFILE_JAVACLASSES_HPP
#define SHARE_CLASSFILE_JAVACLASSES_HPP

#include "classfile/vmClasses.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oopsHierarchy.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.hpp"
#include "runtime/os.hpp"
#include "utilities/macros.hpp"
#include "utilities/utf8.hpp"
#include "utilities/vmEnums.hpp"

class JvmtiThreadState;
class RecordComponent;
class SerializeClosure;
class ObjectWaiter;
class ObjectMonitor;

#define CHECK_INIT(offset)  assert(offset != 0, "should be initialized"); return offset;

// Interface to java.lang.Object objects

class java_lang_Object : AllStatic {
 public:
  static void register_natives(TRAPS);
};

// Interface to java.lang.String objects

// The flags field is a collection of bits representing boolean values used
// internally by the VM.
#define STRING_INJECTED_FIELDS(macro) \
  macro(java_lang_String, flags, byte_signature, false)

class java_lang_String : AllStatic {
 private:
  static int _value_offset;
  static int _hash_offset;
  static int _hashIsZero_offset;
  static int _coder_offset;
  static int _flags_offset;

  static bool _initialized;

  static Handle basic_create(int length, bool byte_arr, TRAPS);

  static inline void set_coder(oop string, jbyte coder);

  // Bitmasks for values in the injected flags field.
  static const uint8_t _deduplication_forbidden_mask = 1 << 0;
  static const uint8_t _deduplication_requested_mask = 1 << 1;

  static int flags_offset() { CHECK_INIT(_flags_offset); }
  // Return the address of the injected flags field.
  static inline uint8_t* flags_addr(oop java_string);
  // Test whether the designated bit of the injected flags field is set.
  static inline bool is_flag_set(oop java_string, uint8_t flag_mask);
  // Atomically test and set the designated bit of the injected flags field,
  // returning true if the bit was already set.
  static bool test_and_set_flag(oop java_string, uint8_t flag_mask);

  static inline unsigned int hash_code_impl(oop java_string, bool update);

 public:

  // Coders
  enum Coder {
    CODER_LATIN1 =  0,
    CODER_UTF16  =  1
  };

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Instance creation
  static Handle create_from_unicode(const jchar* unicode, int len, TRAPS);
  static oop    create_oop_from_unicode(const jchar* unicode, int len, TRAPS);
  static Handle create_from_str(const char* utf8_str, TRAPS);
  static oop    create_oop_from_str(const char* utf8_str, TRAPS);
  static Handle create_from_symbol(const Symbol* symbol, TRAPS);
  static Handle create_from_platform_dependent_str(const char* str, TRAPS);

  static void set_compact_strings(bool value);

  static int value_offset() { CHECK_INIT(_value_offset); }
  static int coder_offset() { CHECK_INIT(_coder_offset); }

  static inline void set_value(oop string, typeArrayOop buffer);

  // Set the deduplication_forbidden flag true.  This flag is sticky; once
  // set it never gets cleared.  This is set when a String is interned in
  // the StringTable, to prevent string deduplication from changing the
  // String's value array.
  static inline void set_deduplication_forbidden(oop java_string);

  // Test and set the deduplication_requested flag.  Returns the old value
  // of the flag.  This flag is sticky; once set it never gets cleared.
  // Some GCs may use this flag when deciding whether to request
  // deduplication of a String, to avoid multiple requests for the same
  // object.
  static inline bool test_and_set_deduplication_requested(oop java_string);

  // Accessors
  static inline typeArrayOop value(oop java_string);
  static inline typeArrayOop value_no_keepalive(oop java_string);
  static inline bool hash_is_set(oop string);
  static inline bool is_latin1(oop java_string);
  static inline bool deduplication_forbidden(oop java_string);
  static inline bool deduplication_requested(oop java_string);
  static inline int length(oop java_string);
  static inline int length(oop java_string, typeArrayOop string_value);
  static size_t utf8_length(oop java_string);
  static size_t utf8_length(oop java_string, typeArrayOop string_value);
  // Legacy variants that truncate the length if needed
  static int    utf8_length_as_int(oop java_string);
  static int    utf8_length_as_int(oop java_string, typeArrayOop string_value);

  // String converters
  static char*  as_utf8_string(oop java_string);
  // `length` is set to the length of the utf8 sequence.
  static char*  as_utf8_string(oop java_string, size_t& length);
  static char*  as_utf8_string_full(oop java_string, char* buf, size_t buflen, size_t& length);
  static char*  as_utf8_string(oop java_string, char* buf, size_t buflen);
  static char*  as_utf8_string(oop java_string, int start, int len);
  static char*  as_utf8_string(oop java_string, typeArrayOop value, char* buf, size_t buflen);
  static char*  as_utf8_string(oop java_string, typeArrayOop value, int start, int len, char* buf, size_t buflen);
  static char*  as_platform_dependent_str(Handle java_string, TRAPS);
  static jchar* as_unicode_string(oop java_string, int& length, TRAPS);
  static jchar* as_unicode_string_or_null(oop java_string, int& length);
  // produce an ascii string with all other values quoted using \u####
  static char*  as_quoted_ascii(oop java_string);

  // Compute the hash value for a java.lang.String object which would
  // contain the characters passed in.
  //
  // As the hash value used by the String object itself, in
  // String.hashCode().  This value is normally calculated in Java code
  // in the String.hashCode method(), but is precomputed for String
  // objects in the shared archive file.
  // hash P(31) from Kernighan & Ritchie
  //
  // For this reason, THIS ALGORITHM MUST MATCH String.hashCode().
  static unsigned int hash_code(const jchar* s, int len) {
    unsigned int h = 0;
    while (len-- > 0) {
      h = 31*h + (unsigned int) *s;
      s++;
    }
    return h;
  }

  static unsigned int hash_code(const jbyte* s, int len) {
    unsigned int h = 0;
    while (len-- > 0) {
      h = 31*h + (((unsigned int) *s) & 0xFF);
      s++;
    }
    return h;
  }

  static unsigned int hash_code(const char* utf8_str, size_t utf8_len) {
    unsigned int h = 0;
    int unicode_length = UTF8::unicode_length(utf8_str, utf8_len);

    jchar c;
    while (unicode_length-- > 0) {
      utf8_str = UTF8::next(utf8_str, &c);
      h = 31 * h + ((unsigned int)c);
    }
    return h;
  }

  static unsigned int hash_code(oop java_string);
  static unsigned int hash_code_noupdate(oop java_string);

  // Compare strings (of different types/encodings), length is the string (array) length
  static bool equals(oop java_string, const jchar* chars, int len);
  static bool equals(oop java_string, const char* utf8_str, size_t utf8_len);
  static bool equals(oop str1, oop str2);
  static inline bool value_equals(typeArrayOop str_value1, typeArrayOop str_value2);

  // Conversion between '.' and '/' formats, and allocate a String from the result.
  static Handle externalize_classname(Symbol* java_name, TRAPS);

  // Conversion
  static Symbol* as_symbol(oop java_string);
  static Symbol* as_symbol_or_null(oop java_string);

  // Tester
  static inline bool is_instance(oop obj);

  // Debugging
  static void print(oop java_string, outputStream* st, int max_length = MaxStringPrintSize);
  friend class JavaClasses;
  friend class StringTable;
};


// Interface to java.lang.Class objects

#define CLASS_INJECTED_FIELDS(macro)                                       \
  macro(java_lang_Class, klass,                  intptr_signature,  false) \
  macro(java_lang_Class, array_klass,            intptr_signature,  false) \
  macro(java_lang_Class, oop_size,               int_signature,     false) \
  macro(java_lang_Class, static_oop_field_count, int_signature,     false) \
  macro(java_lang_Class, source_file,            object_signature,  false) \
  macro(java_lang_Class, init_lock,              object_signature,  false)

class java_lang_Class : AllStatic {
  friend class VMStructs;
  friend class JVMCIVMStructs;

 private:

  // The fake offsets are added by the class loader when java.lang.Class is loaded

  static int _klass_offset;
  static int _array_klass_offset;

  static int _oop_size_offset;
  static int _static_oop_field_count_offset;

  static int _protection_domain_offset;
  static int _init_lock_offset;
  static int _signers_offset;
  static int _class_loader_offset;
  static int _module_offset;
  static int _component_mirror_offset;
  static int _name_offset;
  static int _source_file_offset;
  static int _classData_offset;
  static int _classRedefinedCount_offset;
  static int _reflectionData_offset;
  static int _modifiers_offset;
  static int _is_primitive_offset;

  static bool _offsets_computed;

  static GrowableArray<Klass*>* _fixup_mirror_list;
  static GrowableArray<Klass*>* _fixup_module_field_list;

  static void set_init_lock(oop java_class, oop init_lock);
  static void set_protection_domain(oop java_class, oop protection_domain);
  static void set_class_loader(oop java_class, oop class_loader);
  static void set_component_mirror(oop java_class, oop comp_mirror);
  static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain,
                                       Handle classData, TRAPS);
  static void set_mirror_module_field(JavaThread* current, Klass* K, Handle mirror, Handle module);
 public:
  static void allocate_fixup_lists();
  static void compute_offsets();

  // Instance creation
  static void allocate_mirror(Klass* k, bool is_scratch, Handle protection_domain, Handle classData,
                              Handle& mirror, Handle& comp_mirror, TRAPS); // returns mirror and comp_mirror
  static void create_mirror(Klass* k, Handle class_loader, Handle module,
                            Handle protection_domain, Handle classData, TRAPS);
  static void fixup_mirror(Klass* k, TRAPS);
  static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);

  // Archiving
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  static void create_scratch_mirror(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
  static bool restore_archived_mirror(Klass *k, Handle class_loader, Handle module,
                                      Handle protection_domain,
                                      TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(false);

  static void fixup_module_field(Klass* k, Handle module);

  // Conversion
  static Klass* as_Klass(oop java_class);
  static void set_klass(oop java_class, Klass* klass);
  static BasicType as_BasicType(oop java_class, Klass** reference_klass = nullptr);
  static Symbol* as_signature(oop java_class, bool intern_if_not_found);
  static void print_signature(oop java_class, outputStream *st);
  static const char* as_external_name(oop java_class);
  // Testing
  static bool is_instance(oop obj);

  static bool is_primitive(oop java_class);
  static void set_is_primitive(oop java_class);
  static BasicType primitive_type(oop java_class);
  static oop primitive_mirror(BasicType t);
  // JVM_NewArray support
  static Klass* array_klass_acquire(oop java_class);
  static void release_set_array_klass(oop java_class, Klass* klass);
  // compiler support for class operations
  static int klass_offset()                { CHECK_INIT(_klass_offset); }
  static int array_klass_offset()          { CHECK_INIT(_array_klass_offset); }
  // Support for classRedefinedCount field
  static int classRedefinedCount(oop the_class_mirror);
  static void set_classRedefinedCount(oop the_class_mirror, int value);

  // Support for embedded per-class oops
  static oop  protection_domain(oop java_class);
  static oop  init_lock(oop java_class);
  static void clear_init_lock(oop java_class) {
    set_init_lock(java_class, nullptr);
  }
  static oop  component_mirror(oop java_class);
  static int component_mirror_offset() { return _component_mirror_offset; }
  static objArrayOop signers(oop java_class);
  static oop  class_data(oop java_class);
  static void set_class_data(oop java_class, oop classData);
  static void set_reflection_data(oop java_class, oop reflection_data);
  static int reflection_data_offset() { return _reflectionData_offset; }

  static oop class_loader(oop java_class);
  static void set_module(oop java_class, oop module);
  static oop module(oop java_class);

  static oop name(Handle java_class, TRAPS);

  static oop source_file(oop java_class);
  static void set_source_file(oop java_class, oop source_file);

  static int modifiers(oop java_class);
  static void set_modifiers(oop java_class, u2 value);

  static size_t oop_size(oop java_class);
  static void set_oop_size(HeapWord* java_class, size_t size);
  static int static_oop_field_count(oop java_class);
  static void set_static_oop_field_count(oop java_class, int size);

  static GrowableArray<Klass*>* fixup_mirror_list() {
    return _fixup_mirror_list;
  }
  static void set_fixup_mirror_list(GrowableArray<Klass*>* v) {
    _fixup_mirror_list = v;
  }

  static GrowableArray<Klass*>* fixup_module_field_list() {
    return _fixup_module_field_list;
  }
  static void set_fixup_module_field_list(GrowableArray<Klass*>* v) {
    _fixup_module_field_list = v;
  }

  // Debugging
  friend class JavaClasses;
};

// Interface to java.lang.Thread objects

#define THREAD_INJECTED_FIELDS(macro)                                  \
  macro(java_lang_Thread, jvmti_thread_state, intptr_signature, false) \
  macro(java_lang_Thread, jvmti_VTMS_transition_disable_count, int_signature, false) \
  macro(java_lang_Thread, jvmti_is_in_VTMS_transition, bool_signature, false) \
  JFR_ONLY(macro(java_lang_Thread, jfr_epoch, short_signature, false))

class java_lang_Thread : AllStatic {
  friend class java_lang_VirtualThread;
  friend class JVMCIVMStructs;
 private:
  // Note that for this class the layout changed between JDK1.2 and JDK1.3,
  // so we compute the offsets at startup rather than hard-wiring them.
  static int _holder_offset;
  static int _name_offset;
  static int _contextClassLoader_offset;
  static int _eetop_offset;
  static int _jvmti_thread_state_offset;
  static int _jvmti_VTMS_transition_disable_count_offset;
  static int _jvmti_is_in_VTMS_transition_offset;
  static int _interrupted_offset;
  static int _interruptLock_offset;
  static int _tid_offset;
  static int _continuation_offset;
  static int _park_blocker_offset;
  static int _scopedValueBindings_offset;
  JFR_ONLY(static int _jfr_epoch_offset;)

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Returns the JavaThread associated with the thread obj
  static JavaThread* thread(oop java_thread);
  static JavaThread* thread_acquire(oop java_thread);
  // Set JavaThread for instance
  static void set_thread(oop java_thread, JavaThread* thread);
  static void release_set_thread(oop java_thread, JavaThread* thread);
  // FieldHolder
  static oop holder(oop java_thread);
  // interruptLock
  static oop interrupt_lock(oop java_thread);
  // Interrupted status
  static bool interrupted(oop java_thread);
  static void set_interrupted(oop java_thread, bool val);
  // Name
  static oop name(oop java_thread);
  static void set_name(oop java_thread, oop name);
  // Priority
  static ThreadPriority priority(oop java_thread);
  static void set_priority(oop java_thread, ThreadPriority priority);
  // Thread group
  static oop  threadGroup(oop java_thread);
  // Alive (NOTE: this is not really a field, but provides the correct
  // definition without doing a Java call)
  static bool is_alive(oop java_thread);
  // Daemon
  static bool is_daemon(oop java_thread);
  static void set_daemon(oop java_thread);
  // Context ClassLoader
  static oop context_class_loader(oop java_thread);
  // Stack size hint
  static jlong stackSize(oop java_thread);
  // Thread ID
  static int64_t thread_id(oop java_thread);
  static ByteSize thread_id_offset();
  // Continuation
  static inline oop continuation(oop java_thread);

  static JvmtiThreadState* jvmti_thread_state(oop java_thread);
  static void set_jvmti_thread_state(oop java_thread, JvmtiThreadState* state);
  static int  VTMS_transition_disable_count(oop java_thread);
  static void inc_VTMS_transition_disable_count(oop java_thread);
  static void dec_VTMS_transition_disable_count(oop java_thread);
  static bool is_in_VTMS_transition(oop java_thread);
  static void set_is_in_VTMS_transition(oop java_thread, bool val);
  static int  is_in_VTMS_transition_offset();

  // Clear all scoped value bindings on error
  static void clear_scopedValueBindings(oop java_thread);

  // Blocker object responsible for thread parking
  static oop park_blocker(oop java_thread);

  // Write thread status info to threadStatus field of java.lang.Thread.
  static void set_thread_status(oop java_thread_oop, JavaThreadStatus status);
  // Read thread status info from threadStatus field of java.lang.Thread.
  static JavaThreadStatus get_thread_status(oop java_thread_oop);

  static const char*  thread_status_name(oop java_thread_oop);

  // Fill in current stack trace, can cause GC
  static oop async_get_stack_trace(oop java_thread, TRAPS);

  JFR_ONLY(static u2 jfr_epoch(oop java_thread);)
  JFR_ONLY(static void set_jfr_epoch(oop java_thread, u2 epoch);)
  JFR_ONLY(static int jfr_epoch_offset() { CHECK_INIT(_jfr_epoch_offset); })

  // Debugging
  friend class JavaClasses;
};

// Interface to java.lang.Thread$FieldHolder objects

class java_lang_Thread_FieldHolder : AllStatic {
 private:
  static int _group_offset;
  static int _priority_offset;
  static int _stackSize_offset;
  static int _daemon_offset;
  static int _thread_status_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  static oop threadGroup(oop holder);

  static ThreadPriority priority(oop holder);
  static void set_priority(oop holder, ThreadPriority priority);

  static jlong stackSize(oop holder);

  static bool is_daemon(oop holder);
  static void set_daemon(oop holder, bool val);

  static void set_thread_status(oop holder, JavaThreadStatus status);
  static JavaThreadStatus get_thread_status(oop holder);

  friend class JavaClasses;
};

// Interface to java.lang.Thread$Constants objects

class java_lang_Thread_Constants : AllStatic {
 private:
  static int _static_VTHREAD_GROUP_offset;
  static int _static_NOT_SUPPORTED_CLASSLOADER_offset;

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

 public:
  static oop get_VTHREAD_GROUP();

  friend class JavaClasses;
};

// Interface to java.lang.ThreadGroup objects

class java_lang_ThreadGroup : AllStatic {
 private:
  static int _parent_offset;
  static int _name_offset;
  static int _maxPriority_offset;
  static int _daemon_offset;

  static void compute_offsets();
 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // parent ThreadGroup
  static oop parent(oop java_thread_group);
  // name
  static const char* name(oop java_thread_group);
  // maxPriority in group
  static ThreadPriority maxPriority(oop java_thread_group);
  // Daemon
  static bool is_daemon(oop java_thread_group);

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.VirtualThread objects
#define VTHREAD_INJECTED_FIELDS(macro)                                           \
  macro(java_lang_VirtualThread,   objectWaiter,  intptr_signature,       false)

class java_lang_VirtualThread : AllStatic {
 private:
  static int static_vthread_scope_offset;
  static int _carrierThread_offset;
  static int _continuation_offset;
  static int _state_offset;
  static int _next_offset;
  static int _onWaitingList_offset;
  static int _notified_offset;
  static int _recheckInterval_offset;
  static int _timeout_offset;
  static int _objectWaiter_offset;
  JFR_ONLY(static int _jfr_epoch_offset;)
 public:
  enum {
    NEW           = 0,
    STARTED       = 1,
    RUNNING       = 2,
    PARKING       = 3,
    PARKED        = 4,
    PINNED        = 5,
    TIMED_PARKING = 6,
    TIMED_PARKED  = 7,
    TIMED_PINNED  = 8,
    UNPARKED      = 9,
    YIELDING      = 10,
    YIELDED       = 11,
    BLOCKING      = 12,
    BLOCKED       = 13,
    UNBLOCKED     = 14,
    WAITING       = 15,
    WAIT          = 16,  // waiting in Object.wait
    TIMED_WAITING = 17,
    TIMED_WAIT    = 18,  // waiting in timed-Object.wait
    TERMINATED    = 99,

    // additional state bits
    SUSPENDED    = 1 << 8,   // suspended when unmounted
  };

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::VirtualThread_klass());
  }
  static bool is_instance(oop obj);

  static oop vthread_scope();
  static oop carrier_thread(oop vthread);
  static oop continuation(oop vthread);
  static int state(oop vthread);
  static void set_state(oop vthread, int state);
  static int cmpxchg_state(oop vthread, int old_state, int new_state);
  static oop next(oop vthread);
  static void set_next(oop vthread, oop next_vthread);
  static bool set_onWaitingList(oop vthread, OopHandle& list_head);
  static jlong timeout(oop vthread);
  static void set_timeout(oop vthread, jlong value);
  static void set_notified(oop vthread, jboolean value);
  static bool is_preempted(oop vthread);
  static JavaThreadStatus map_state_to_thread_status(int state);

  static inline ObjectWaiter* objectWaiter(oop vthread);
  static inline void set_objectWaiter(oop vthread, ObjectWaiter* waiter);
  static ObjectMonitor* current_pending_monitor(oop vthread);
  static ObjectMonitor* current_waiting_monitor(oop vthread);
};


// Interface to java.lang.Throwable objects

class java_lang_Throwable: AllStatic {
  friend class BacktraceBuilder;
  friend class BacktraceIterator;

 private:
  // Trace constants
  enum {
    trace_methods_offset = 0,
    trace_bcis_offset    = 1,
    trace_mirrors_offset = 2,
    trace_names_offset   = 3,
    trace_conts_offset   = 4,
    trace_next_offset    = 5,
    trace_hidden_offset  = 6,
    trace_size           = 7,
    trace_chunk_size     = 32
  };

  static int _backtrace_offset;
  static int _detailMessage_offset;
  static int _stackTrace_offset;
  static int _depth_offset;
  static int _cause_offset;
  static int _static_unassigned_stacktrace_offset;

  // StackTrace (programmatic access, new since 1.4)
  static void clear_stacktrace(oop throwable);
  // Stacktrace (post JDK 1.7.0 to allow immutability protocol to be followed)
  static void set_stacktrace(oop throwable, oop st_element_array);
  static oop unassigned_stacktrace();

 public:
  // Backtrace
  static oop backtrace(oop throwable);
  static void set_backtrace(oop throwable, oop value);
  static int depth(oop throwable);
  static void set_depth(oop throwable, int value);
  // Message
  static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); }
  static oop message(oop throwable);
  static const char* message_as_utf8(oop throwable);
  static void set_message(oop throwable, oop value);

  static oop cause(oop throwable);

  static void print_stack_element(outputStream *st, Method* method, int bci);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Allocate space for backtrace (created but stack trace not filled in)
  static void allocate_backtrace(Handle throwable, TRAPS);
  // Fill in current stack trace for throwable with preallocated backtrace (no GC)
  static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable);
  // Fill in current stack trace, can cause GC
  static void fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS);
  static void fill_in_stack_trace(Handle throwable, const methodHandle& method = methodHandle());

  // Programmatic access to stack trace
  static void get_stack_trace_elements(int depth, Handle backtrace, objArrayHandle stack_trace, TRAPS);

  // For recreating class initialization error exceptions.
  static Handle create_initialization_error(JavaThread* current, Handle throwable);

  // Printing
  static void print(oop throwable, outputStream* st);
  static void print_stack_trace(Handle throwable, outputStream* st);
  static void java_printStackTrace(Handle throwable, TRAPS);
  // Debugging
  friend class JavaClasses;
  // Gets the method and bci of the top frame (TOS). Returns false if this failed.
  static bool get_top_method_and_bci(oop throwable, Method** method, int* bci);
};


// Interface to java.lang.reflect.AccessibleObject objects

class java_lang_reflect_AccessibleObject: AllStatic {
 private:
  // Note that to reduce dependencies on the JDK we compute these
  // offsets at run-time.
  static int _override_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static jboolean override(oop reflect);
  static void set_override(oop reflect, jboolean value);

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.reflect.Method objects

class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject {
 private:
  // Note that to reduce dependencies on the JDK we compute these
  // offsets at run-time.
  static int _clazz_offset;
  static int _name_offset;
  static int _returnType_offset;
  static int _parameterTypes_offset;
  static int _exceptionTypes_offset;
  static int _slot_offset;
  static int _modifiers_offset;
  static int _signature_offset;
  static int _annotations_offset;
  static int _parameter_annotations_offset;
  static int _annotation_default_offset;

  static void compute_offsets();
 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Allocation
  static Handle create(TRAPS);

  // Accessors
  static oop clazz(oop reflect);
  static void set_clazz(oop reflect, oop value);

  static void set_name(oop method, oop value);

  static oop return_type(oop method);
  static void set_return_type(oop method, oop value);

  static oop parameter_types(oop method);
  static void set_parameter_types(oop method, oop value);

  static int slot(oop reflect);
  static void set_slot(oop reflect, int value);

  static void set_exception_types(oop method, oop value);
  static void set_modifiers(oop method, int value);
  static void set_signature(oop method, oop value);
  static void set_annotations(oop method, oop value);
  static void set_parameter_annotations(oop method, oop value);
  static void set_annotation_default(oop method, oop value);

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.reflect.Constructor objects

class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject {
 private:
  // Note that to reduce dependencies on the JDK we compute these
  // offsets at run-time.
  static int _clazz_offset;
  static int _parameterTypes_offset;
  static int _exceptionTypes_offset;
  static int _slot_offset;
  static int _modifiers_offset;
  static int _signature_offset;
  static int _annotations_offset;
  static int _parameter_annotations_offset;

  static void compute_offsets();
 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Allocation
  static Handle create(TRAPS);

  // Accessors
  static oop clazz(oop reflect);
  static void set_clazz(oop reflect, oop value);

  static oop parameter_types(oop constructor);
  static void set_parameter_types(oop constructor, oop value);

  static int slot(oop reflect);
  static void set_slot(oop reflect, int value);

  static void set_exception_types(oop constructor, oop value);
  static void set_modifiers(oop constructor, int value);
  static void set_signature(oop constructor, oop value);
  static void set_annotations(oop constructor, oop value);
  static void set_parameter_annotations(oop method, oop value);

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.reflect.Field objects

class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject {
 private:
  // Note that to reduce dependencies on the JDK we compute these
  // offsets at run-time.
  static int _clazz_offset;
  static int _name_offset;
  static int _type_offset;
  static int _slot_offset;
  static int _modifiers_offset;
  static int _trusted_final_offset;
  static int _signature_offset;
  static int _annotations_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Allocation
  static Handle create(TRAPS);

  // Accessors
  static oop clazz(oop reflect);
  static void set_clazz(oop reflect, oop value);

  static oop name(oop field);
  static void set_name(oop field, oop value);

  static oop type(oop field);
  static void set_type(oop field, oop value);

  static int slot(oop reflect);
  static void set_slot(oop reflect, int value);

  static int modifiers(oop field);
  static void set_modifiers(oop field, int value);

  static void set_trusted_final(oop field);

  static void set_signature(oop constructor, oop value);
  static void set_annotations(oop constructor, oop value);

  // Debugging
  friend class JavaClasses;
};

class java_lang_reflect_Parameter {
 private:
  // Note that to reduce dependencies on the JDK we compute these
  // offsets at run-time.
  static int _name_offset;
  static int _modifiers_offset;
  static int _index_offset;
  static int _executable_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Allocation
  static Handle create(TRAPS);

  // Accessors
  static oop name(oop field);
  static void set_name(oop field, oop value);

  static int index(oop reflect);
  static void set_index(oop reflect, int value);

  static int modifiers(oop reflect);
  static void set_modifiers(oop reflect, int value);

  static oop executable(oop constructor);
  static void set_executable(oop constructor, oop value);

  friend class JavaClasses;
};

#define MODULE_INJECTED_FIELDS(macro)                            \
  macro(java_lang_Module, module_entry, intptr_signature, false)

class java_lang_Module {
  private:
    static int _loader_offset;
    static int _name_offset;
    static int _module_entry_offset;

    static void compute_offsets();

  public:
    static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

    // Allocation
    static Handle create(Handle loader, Handle module_name, TRAPS);

    // Testers
    static bool is_instance(oop obj);

    // Accessors
    static oop loader(oop module);
    static void set_loader(oop module, oop value);

    // CDS
    static int module_entry_offset() { return _module_entry_offset; }

    static oop name(oop module);
    static void set_name(oop module, oop value);

    static ModuleEntry* module_entry(oop module);
    static ModuleEntry* module_entry_raw(oop module);
    static void set_module_entry(oop module, ModuleEntry* module_entry);

  friend class JavaClasses;
};

// Interface to jdk.internal.reflect.ConstantPool objects
class reflect_ConstantPool {
 private:
  // Note that to reduce dependencies on the JDK we compute these
  // offsets at run-time.
  static int _oop_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Allocation
  static Handle create(TRAPS);

  // Accessors
  static void set_cp(oop reflect, ConstantPool* value);
  static int oop_offset() { CHECK_INIT(_oop_offset); }

  static ConstantPool* get_cp(oop reflect);

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang primitive type boxing objects:
//  - java.lang.Boolean
//  - java.lang.Character
//  - java.lang.Float
//  - java.lang.Double
//  - java.lang.Byte
//  - java.lang.Short
//  - java.lang.Integer
//  - java.lang.Long

// This could be separated out into 8 individual classes.

class java_lang_boxing_object: AllStatic {
 private:
  static int _value_offset;
  static int _long_value_offset;

  static void compute_offsets();
  static oop initialize_and_allocate(BasicType type, TRAPS);
 public:
  // Allocation. Returns a boxed value, or null for invalid type.
  static oop create(BasicType type, jvalue* value, TRAPS);
  // Accessors. Returns the basic type being boxed, or T_ILLEGAL for invalid oop.
  static BasicType get_value(oop box, jvalue* value);
  static BasicType set_value(oop box, jvalue* value);
  static BasicType basic_type(oop box);
  static bool is_instance(oop box)                 { return basic_type(box) != T_ILLEGAL; }
  static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
  static void print(oop box, outputStream* st)     { jvalue value;  print(get_value(box, &value), &value, st); }
  static void print(BasicType type, jvalue* value, outputStream* st);

  static int value_offset(BasicType type) {
    return is_double_word_type(type) ? _long_value_offset : _value_offset;
  }

  static void serialize_offsets(SerializeClosure* f);

  // Debugging
  friend class JavaClasses;
};



// Interface to java.lang.ref.Reference objects

class java_lang_ref_Reference: AllStatic {
  static int _referent_offset;
  static int _queue_offset;
  static int _next_offset;
  static int _discovered_offset;

  static bool _offsets_initialized;

 public:
  // Accessors
  static inline oop weak_referent_no_keepalive(oop ref);
  static inline oop weak_referent(oop ref);
  static inline oop phantom_referent_no_keepalive(oop ref);
  static inline oop unknown_referent_no_keepalive(oop ref);
  static inline void clear_referent(oop ref);
  static inline void clear_referent_raw(oop ref);
  static inline HeapWord* referent_addr_raw(oop ref);
  static inline oop next(oop ref);
  static inline void set_next(oop ref, oop value);
  static inline void set_next_raw(oop ref, oop value);
  static inline HeapWord* next_addr_raw(oop ref);
  static inline oop discovered(oop ref);
  static inline void set_discovered(oop ref, oop value);
  static inline void set_discovered_raw(oop ref, oop value);
  static inline HeapWord* discovered_addr_raw(oop ref);
  static bool is_referent_field(oop obj, ptrdiff_t offset);
  static inline bool is_final(oop ref);
  static inline bool is_phantom(oop ref);
  static inline bool is_weak(oop ref);
  static inline bool is_soft(oop ref);

  static int referent_offset()    { CHECK_INIT(_referent_offset); }
  static int queue_offset()       { CHECK_INIT(_queue_offset); }
  static int next_offset()        { CHECK_INIT(_next_offset); }
  static int discovered_offset()  { CHECK_INIT(_discovered_offset); }

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};


// Interface to java.lang.ref.SoftReference objects

class java_lang_ref_SoftReference: public java_lang_ref_Reference {
  static int _timestamp_offset;
  static int _static_clock_offset;

 public:
  // Accessors
  static jlong timestamp(oop ref);

  // Accessors for statics
  static jlong clock();
  static void set_clock(jlong value);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

// Interface to java.lang.invoke.MethodHandle objects

class java_lang_invoke_MethodHandle: AllStatic {
  friend class JavaClasses;

 private:
  static int _type_offset;               // the MethodType of this MH
  static int _form_offset;               // the LambdaForm of this MH

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static oop            type(oop mh);
  static void       set_type(oop mh, oop mtype);

  static oop            form(oop mh);
  static void       set_form(oop mh, oop lform);

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::MethodHandle_klass());
  }
  static bool is_instance(oop obj);

  // Accessors for code generation:
  static int type_offset()             { CHECK_INIT(_type_offset); }
  static int form_offset()             { CHECK_INIT(_form_offset); }
};

// Interface to java.lang.invoke.DirectMethodHandle objects

class java_lang_invoke_DirectMethodHandle: AllStatic {
  friend class JavaClasses;

 private:
  static int _member_offset;               // the MemberName of this DMH

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static oop  member(oop mh);

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::DirectMethodHandle_klass());
  }
  static bool is_instance(oop obj);

  // Accessors for code generation:
  static int member_offset()           { CHECK_INIT(_member_offset); }
};

// Interface to java.lang.invoke.LambdaForm objects
// (These are a private interface for managing adapter code generation.)

class java_lang_invoke_LambdaForm: AllStatic {
  friend class JavaClasses;

 private:
  static int _vmentry_offset;  // type is MemberName

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static oop            vmentry(oop lform);

  // Testers
  static bool is_subclass(Klass* klass) {
    return vmClasses::LambdaForm_klass() != nullptr &&
      klass->is_subclass_of(vmClasses::LambdaForm_klass());
  }
  static bool is_instance(oop obj);

  // Accessors for code generation:
  static int vmentry_offset()          { CHECK_INIT(_vmentry_offset); }
};

// Interface to java.lang.invoke.NativeEntryPoint objects
// (These are a private interface for managing adapter code generation.)

class jdk_internal_foreign_abi_NativeEntryPoint: AllStatic {
  friend class JavaClasses;

 private:
  static int _method_type_offset;
  static int _downcall_stub_address_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static oop        method_type(oop entry);
  static jlong      downcall_stub_address(oop entry);

  // Testers
  static bool is_subclass(Klass* klass) {
    return vmClasses::NativeEntryPoint_klass() != nullptr &&
      klass->is_subclass_of(vmClasses::NativeEntryPoint_klass());
  }
  static bool is_instance(oop obj);

  // Accessors for code generation:
  static int method_type_offset_in_bytes()           { return _method_type_offset; }
  static int downcall_stub_address_offset_in_bytes() { return _downcall_stub_address_offset; }
};

class jdk_internal_foreign_abi_ABIDescriptor: AllStatic {
  friend class JavaClasses;

 private:
  static int _inputStorage_offset;
  static int _outputStorage_offset;
  static int _volatileStorage_offset;
  static int _stackAlignment_offset;
  static int _shadowSpace_offset;
  static int _scratch1_offset;
  static int _scratch2_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static objArrayOop inputStorage(oop entry);
  static objArrayOop outputStorage(oop entry);
  static objArrayOop volatileStorage(oop entry);
  static jint        stackAlignment(oop entry);
  static jint        shadowSpace(oop entry);
  static oop         scratch1(oop entry);
  static oop         scratch2(oop entry);

  // Testers
  static bool is_subclass(Klass* klass) {
    return vmClasses::ABIDescriptor_klass() != nullptr &&
      klass->is_subclass_of(vmClasses::ABIDescriptor_klass());
  }
  static bool is_instance(oop obj);
};

class jdk_internal_foreign_abi_VMStorage: AllStatic {
  friend class JavaClasses;

 private:
  static int _type_offset;
  static int _indexOrOffset_offset;
  static int _segmentMaskOrSize_offset;
  static int _debugName_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static jbyte  type(oop entry);
  static jint   index_or_offset(oop entry);
  static jshort segment_mask_or_size(oop entry);
  static oop    debugName(oop entry);

  // Testers
  static bool is_subclass(Klass* klass) {
    return vmClasses::VMStorage_klass() != nullptr &&
      klass->is_subclass_of(vmClasses::VMStorage_klass());
  }
  static bool is_instance(oop obj);
};

class jdk_internal_foreign_abi_CallConv: AllStatic {
  friend class JavaClasses;

 private:
  static int _argRegs_offset;
  static int _retRegs_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Accessors
  static objArrayOop argRegs(oop entry);
  static objArrayOop retRegs(oop entry);

  // Testers
  static bool is_subclass(Klass* klass) {
    return vmClasses::CallConv_klass() != nullptr &&
      klass->is_subclass_of(vmClasses::CallConv_klass());
  }
  static bool is_instance(oop obj);
};

// Interface to java.lang.invoke.MemberName objects
// (These are a private interface for Java code to query the class hierarchy.)

#define RESOLVEDMETHOD_INJECTED_FIELDS(macro)                                   \
  macro(java_lang_invoke_ResolvedMethodName, vmtarget, intptr_signature, false)

class java_lang_invoke_ResolvedMethodName : AllStatic {
  friend class JavaClasses;

  static int _vmtarget_offset;
  static int _vmholder_offset;

  static void compute_offsets();
 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  static int vmtarget_offset() { CHECK_INIT(_vmtarget_offset); }

  static Method* vmtarget(oop resolved_method);
  static void set_vmtarget(oop resolved_method, Method* method);

  static void set_vmholder(oop resolved_method, oop holder);

  // find or create resolved member name
  static oop find_resolved_method(const methodHandle& m, TRAPS);

  static bool is_instance(oop resolved_method);
};


#define MEMBERNAME_INJECTED_FIELDS(macro)                               \
  macro(java_lang_invoke_MemberName, vmindex,  intptr_signature, false)


class java_lang_invoke_MemberName: AllStatic {
  friend class JavaClasses;

 private:
  // From java.lang.invoke.MemberName:
  //    private Class<?>   clazz;       // class in which the method is defined
  //    private String     name;        // may be null if not yet materialized
  //    private Object     type;        // may be null if not yet materialized
  //    private int        flags;       // modifier bits; see reflect.Modifier
  //    private ResolvedMethodName method;    // holds VM-specific target value
  //    private intptr_t   vmindex;     // member index within class or interface
  static int _clazz_offset;
  static int _name_offset;
  static int _type_offset;
  static int _flags_offset;
  static int _method_offset;
  static int _vmindex_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  // Accessors
  static oop            clazz(oop mname);
  static void       set_clazz(oop mname, oop clazz);

  static oop            type(oop mname);
  static void       set_type(oop mname, oop type);

  static oop            name(oop mname);
  static void       set_name(oop mname, oop name);

  static int            flags(oop mname);
  static void       set_flags(oop mname, int flags);

  // Link through ResolvedMethodName field to get Method*
  static Method*        vmtarget(oop mname);
  static void       set_method(oop mname, oop method);

  static intptr_t       vmindex(oop mname);
  static void       set_vmindex(oop mname, intptr_t index);

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::MemberName_klass());
  }
  static bool is_instance(oop obj);

  static bool is_method(oop obj);

  // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
  enum {
    MN_IS_METHOD             = 0x00010000, // method (not constructor)
    MN_IS_CONSTRUCTOR        = 0x00020000, // constructor
    MN_IS_FIELD              = 0x00040000, // field
    MN_IS_TYPE               = 0x00080000, // nested type
    MN_CALLER_SENSITIVE      = 0x00100000, // @CallerSensitive annotation detected
    MN_TRUSTED_FINAL         = 0x00200000, // trusted final field
    MN_HIDDEN_MEMBER         = 0x00400000, // @Hidden annotation detected
    MN_REFERENCE_KIND_SHIFT  = 24, // refKind
    MN_REFERENCE_KIND_MASK   = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
    MN_NESTMATE_CLASS        = 0x00000001,
    MN_HIDDEN_CLASS          = 0x00000002,
    MN_STRONG_LOADER_LINK    = 0x00000004,
    MN_ACCESS_VM_ANNOTATIONS = 0x00000008,
    // Lookup modes
    MN_MODULE_MODE           = 0x00000010,
    MN_UNCONDITIONAL_MODE    = 0x00000020,
    MN_TRUSTED_MODE          = -1
  };

  // Accessors for code generation:
  static int clazz_offset()   { CHECK_INIT(_clazz_offset); }
  static int type_offset()    { CHECK_INIT(_type_offset); }
  static int flags_offset()   { CHECK_INIT(_flags_offset); }
  static int method_offset()  { CHECK_INIT(_method_offset); }
  static int vmindex_offset() { CHECK_INIT(_vmindex_offset); }
};


// Interface to java.lang.invoke.MethodType objects

class java_lang_invoke_MethodType: AllStatic {
  friend class JavaClasses;

 private:
  static int _rtype_offset;
  static int _ptypes_offset;

  static void compute_offsets();

 public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  // Accessors
  static oop            rtype(oop mt);
  static objArrayOop    ptypes(oop mt);

  static oop            ptype(oop mt, int index);
  static int            ptype_count(oop mt);

  static int            ptype_slot_count(oop mt);  // extra counts for long/double
  static int            rtype_slot_count(oop mt);  // extra counts for long/double

  static Symbol*        as_signature(oop mt, bool intern_if_not_found);
  static void           print_signature(oop mt, outputStream* st);

  static bool is_instance(oop obj);

  static bool equals(oop mt1, oop mt2);

  // Accessors for code generation:
  static int rtype_offset()  { CHECK_INIT(_rtype_offset); }
  static int ptypes_offset() { CHECK_INIT(_ptypes_offset); }
};


// Interface to java.lang.invoke.CallSite objects
#define CALLSITE_INJECTED_FIELDS(macro) \
  macro(java_lang_invoke_CallSite, vmdependencies, intptr_signature, false) \
  macro(java_lang_invoke_CallSite, last_cleanup, long_signature, false)

class java_lang_invoke_CallSite: AllStatic {
  friend class JavaClasses;

private:
  static int _target_offset;
  static int _vmdependencies_offset;
  static int _last_cleanup_offset;

  static void compute_offsets();

public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  // Accessors
  static oop              target(          oop site);
  static void         set_target(          oop site, oop target);
  static void         set_target_volatile( oop site, oop target);

  static DependencyContext vmdependencies(oop call_site);

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::CallSite_klass());
  }
  static bool is_instance(oop obj);

  // Accessors for code generation:
  static int target_offset()  { CHECK_INIT(_target_offset); }
};

// Interface to java.lang.invoke.ConstantCallSite objects

class java_lang_invoke_ConstantCallSite: AllStatic {
  friend class JavaClasses;

private:
  static int _is_frozen_offset;

  static void compute_offsets();

public:
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  // Accessors
  static jboolean is_frozen(oop site);

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::ConstantCallSite_klass());
  }
  static bool is_instance(oop obj);
};

// Interface to java.lang.ClassLoader objects

#define CLASSLOADER_INJECTED_FIELDS(macro)                            \
  macro(java_lang_ClassLoader, loader_data,  intptr_signature, false)

class java_lang_ClassLoader : AllStatic {
 private:
  static int _loader_data_offset;
  static int _parent_offset;
  static int _parallelCapable_offset;
  static int _name_offset;
  static int _nameAndId_offset;
  static int _unnamedModule_offset;

  static void compute_offsets();

 public:
  // Support for CDS
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  static int loader_data_offset() { return  _loader_data_offset; }

  static ClassLoaderData* loader_data_acquire(oop loader);
  static ClassLoaderData* loader_data(oop loader);
  static void release_set_loader_data(oop loader, ClassLoaderData* new_data);

  static oop parent(oop loader);
  static oop parent_no_keepalive(oop loader);
  static oop name(oop loader);
  static oop nameAndId(oop loader);
  static bool isAncestor(oop loader, oop cl);

  // Support for parallelCapable field
  static bool parallelCapable(oop the_class_mirror);

  static bool is_trusted_loader(oop loader);

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::ClassLoader_klass());
  }
  static bool is_instance(oop obj);

  static oop unnamedModule(oop loader);

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.System objects

class java_lang_System : AllStatic {
 private:
  static int _static_in_offset;
  static int _static_out_offset;
  static int _static_err_offset;

 public:
  static int  in_offset() { CHECK_INIT(_static_in_offset); }
  static int out_offset() { CHECK_INIT(_static_out_offset); }
  static int err_offset() { CHECK_INIT(_static_err_offset); }

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.StackTraceElement objects

class java_lang_StackTraceElement: AllStatic {
 private:
  static int _declaringClassObject_offset;
  static int _classLoaderName_offset;
  static int _moduleName_offset;
  static int _moduleVersion_offset;
  static int _declaringClass_offset;
  static int _methodName_offset;
  static int _fileName_offset;
  static int _lineNumber_offset;

  // Setters
  static void set_classLoaderName(oop element, oop value);
  static void set_moduleName(oop element, oop value);
  static void set_moduleVersion(oop element, oop value);
  static void set_declaringClass(oop element, oop value);
  static void set_methodName(oop element, oop value);
  static void set_fileName(oop element, oop value);
  static void set_lineNumber(oop element, int value);
  static void set_declaringClassObject(oop element, oop value);

  static void decode_file_and_line(Handle java_mirror, InstanceKlass* holder, int version,
                                   const methodHandle& method, int bci,
                                   Symbol*& source, oop& source_file, int& line_number, TRAPS);

 public:
  // Create an instance of StackTraceElement
  static oop create(const methodHandle& method, int bci, TRAPS);

  static void fill_in(Handle element, InstanceKlass* holder, const methodHandle& method,
                      int version, int bci, Symbol* name, TRAPS);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

#if INCLUDE_JVMCI
  static void decode(const methodHandle& method, int bci, Symbol*& fileName, int& lineNumber, TRAPS);
#endif

  // Debugging
  friend class JavaClasses;
};


class Backtrace: AllStatic {
 public:
  // Helper backtrace functions to store bci|version together.
  static int merge_bci_and_version(int bci, int version);
  static int merge_mid_and_cpref(int mid, int cpref);
  static int bci_at(unsigned int merged);
  static int version_at(unsigned int merged);
  static int mid_at(unsigned int merged);
  static int cpref_at(unsigned int merged);
  static int get_line_number(Method* method, int bci);
  static Symbol* get_source_file_name(InstanceKlass* holder, int version);

  // Debugging
  friend class JavaClasses;
};

class java_lang_ClassFrameInfo: AllStatic {
private:
  static int _classOrMemberName_offset;
  static int _flags_offset;

public:
  static oop  classOrMemberName(oop info);
  static int  flags(oop info);

  // Setters
  static void init_class(Handle stackFrame, const methodHandle& m);
  static void init_method(Handle stackFrame, const methodHandle& m, TRAPS);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Debugging
  friend class JavaClasses;
};

// Interface to java.lang.StackFrameInfo objects

#define STACKFRAMEINFO_INJECTED_FIELDS(macro)                      \
  macro(java_lang_StackFrameInfo, version, short_signature, false)

class java_lang_StackFrameInfo: AllStatic {
private:
  static int _type_offset;
  static int _name_offset;
  static int _bci_offset;
  static int _version_offset;
  static int _contScope_offset;

public:
  // Getters
  static oop name(oop info);
  static oop type(oop info);
  static Method* get_method(oop info);

  // Setters
  static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, oop cont, TRAPS);
  static void set_name(oop info, oop value);
  static void set_type(oop info, oop value);
  static void set_bci(oop info, int value);

  static void set_version(oop info, short value);
  static void set_contScope(oop info, oop value);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  static void to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS);

  // Debugging
  friend class JavaClasses;
};

class java_lang_LiveStackFrameInfo: AllStatic {
 private:
  static int _monitors_offset;
  static int _locals_offset;
  static int _operands_offset;
  static int _mode_offset;

 public:
  static void set_monitors(oop info, oop value);
  static void set_locals(oop info, oop value);
  static void set_operands(oop info, oop value);
  static void set_mode(oop info, int value);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Debugging
  friend class JavaClasses;
};

// Interface to java.lang.reflect.RecordComponent objects

class java_lang_reflect_RecordComponent: AllStatic {
 private:
  static int _clazz_offset;
  static int _name_offset;
  static int _type_offset;
  static int _accessor_offset;
  static int _signature_offset;
  static int _annotations_offset;
  static int _typeAnnotations_offset;

  // Setters
  static void set_clazz(oop element, oop value);
  static void set_name(oop element, oop value);
  static void set_type(oop element, oop value);
  static void set_accessor(oop element, oop value);
  static void set_signature(oop element, oop value);
  static void set_annotations(oop element, oop value);
  static void set_typeAnnotations(oop element, oop value);

 public:
  // Create an instance of RecordComponent
  static oop create(InstanceKlass* holder, RecordComponent* component, TRAPS);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Debugging
  friend class JavaClasses;
};


// Interface to java.lang.AssertionStatusDirectives objects

class java_lang_AssertionStatusDirectives: AllStatic {
 private:
  static int _classes_offset;
  static int _classEnabled_offset;
  static int _packages_offset;
  static int _packageEnabled_offset;
  static int _deflt_offset;

 public:
  // Setters
  static void set_classes(oop obj, oop val);
  static void set_classEnabled(oop obj, oop val);
  static void set_packages(oop obj, oop val);
  static void set_packageEnabled(oop obj, oop val);
  static void set_deflt(oop obj, bool val);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Debugging
  friend class JavaClasses;
};


class java_util_concurrent_locks_AbstractOwnableSynchronizer : AllStatic {
 private:
  static int  _owner_offset;
 public:
  static void compute_offsets();
  static oop  get_owner_threadObj(oop obj);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

 // Interface to jdk.internal.misc.UnsafeConsants

class jdk_internal_misc_UnsafeConstants : AllStatic {
 public:
  static void set_unsafe_constants();
  static void compute_offsets() { }
  static void serialize_offsets(SerializeClosure* f) { }
};

// Interface to jdk.internal.vm.vector.VectorSupport.VectorPayload objects

class vector_VectorPayload : AllStatic {
 private:
  static int _payload_offset;
 public:
  static void set_payload(oop o, oop val);

  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;

  // Testers
  static bool is_subclass(Klass* klass) {
    return klass->is_subclass_of(vmClasses::vector_VectorPayload_klass());
  }
  static bool is_instance(oop obj);
};

class java_lang_Integer : AllStatic {
public:
  static jint value(oop obj);
};

class java_lang_Long : AllStatic {
public:
  static jlong value(oop obj);
};

class java_lang_Character : AllStatic {
public:
  static jchar value(oop obj);
};

class java_lang_Short : AllStatic {
public:
  static jshort value(oop obj);
};

class java_lang_Byte : AllStatic {
public:
  static jbyte value(oop obj);
};

class java_lang_Boolean : AllStatic {
 private:
  static int _static_TRUE_offset;
  static int _static_FALSE_offset;
 public:
  static Symbol* symbol();
  static void compute_offsets(InstanceKlass* k);
  static oop  get_TRUE(InstanceKlass *k);
  static oop  get_FALSE(InstanceKlass *k);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
  static jboolean value(oop obj);
};

class java_lang_Integer_IntegerCache : AllStatic {
 private:
  static int _static_cache_offset;
 public:
  static Symbol* symbol();
  static void compute_offsets(InstanceKlass* k);
  static objArrayOop  cache(InstanceKlass *k);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

class java_lang_Long_LongCache : AllStatic {
 private:
  static int _static_cache_offset;
 public:
  static Symbol* symbol();
  static void compute_offsets(InstanceKlass* k);
  static objArrayOop  cache(InstanceKlass *k);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

class java_lang_Character_CharacterCache : AllStatic {
 private:
  static int _static_cache_offset;
 public:
  static Symbol* symbol();
  static void compute_offsets(InstanceKlass* k);
  static objArrayOop  cache(InstanceKlass *k);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

class java_lang_Short_ShortCache : AllStatic {
 private:
  static int _static_cache_offset;
 public:
  static Symbol* symbol();
  static void compute_offsets(InstanceKlass* k);
  static objArrayOop  cache(InstanceKlass *k);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

class java_lang_Byte_ByteCache : AllStatic {
 private:
  static int _static_cache_offset;
 public:
  static Symbol* symbol();
  static void compute_offsets(InstanceKlass* k);
  static objArrayOop  cache(InstanceKlass *k);
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};


// Interface to java.lang.InternalError objects

#define INTERNALERROR_INJECTED_FIELDS(macro)                      \
  macro(java_lang_InternalError, during_unsafe_access, bool_signature, false)

class java_lang_InternalError : AllStatic {
 private:
  static int _during_unsafe_access_offset;
 public:
  static jboolean during_unsafe_access(oop internal_error);
  static void set_during_unsafe_access(oop internal_error);
  static void compute_offsets();
  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};

// Use to declare fields that need to be injected into Java classes
// for the JVM to use.  The name_index and signature_index are
// declared in vmSymbols.  The may_be_java flag is used to declare
// fields that might already exist in Java but should be injected if
// they don't.  Otherwise the field is unconditionally injected and
// the JVM uses the injected one.  This is to ensure that name
// collisions don't occur.  In general may_be_java should be false
// unless there's a good reason.

class InjectedField {
 public:
  const vmClassID klass_id;
  const vmSymbolID name_index;
  const vmSymbolID signature_index;
  const bool           may_be_java;


  Klass* klass() const      { return vmClasses::klass_at(klass_id); }
  Symbol* name() const      { return lookup_symbol(name_index); }
  Symbol* signature() const { return lookup_symbol(signature_index); }

  int compute_offset();

  // Find the Symbol for this index
  static Symbol* lookup_symbol(vmSymbolID symbol_index) {
    return Symbol::vm_symbol_at(symbol_index);
  }
};


// Interface to hard-coded offset checking

enum class InjectedFieldID : int;

class JavaClasses : AllStatic {
 private:

  static InjectedField _injected_fields[];

  static bool check_offset(const char *klass_name, int offset, const char *field_name, const char* field_sig) PRODUCT_RETURN0;
 public:

  static int compute_injected_offset(InjectedFieldID id);

  static void compute_offsets();
  static void check_offsets() PRODUCT_RETURN;
  static void serialize_offsets(SerializeClosure* soc) NOT_CDS_RETURN;
  static InjectedField* get_injected(Symbol* class_name, int* field_count);
  static bool is_supported_for_archiving(oop obj) NOT_CDS_JAVA_HEAP_RETURN_(false);

  static void compute_offset(int &dest_offset,
                             InstanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol,
                             bool is_static = false);
  static void compute_offset(int& dest_offset, InstanceKlass* ik,
                             const char* name_string, Symbol* signature_symbol,
                             bool is_static = false);
};

#undef CHECK_INIT

#endif // SHARE_CLASSFILE_JAVACLASSES_HPP
