diff a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -23,10 +23,11 @@
  */
 
 #ifndef SHARE_OOPS_INSTANCEKLASS_HPP
 #define SHARE_OOPS_INSTANCEKLASS_HPP
 
+#include "code/vmreg.hpp"
 #include "memory/referenceType.hpp"
 #include "oops/annotations.hpp"
 #include "oops/constMethod.hpp"
 #include "oops/fieldInfo.hpp"
 #include "oops/instanceKlassFlags.hpp"
@@ -54,10 +55,11 @@
 //    [EMBEDDED Java vtable             ] size in words = vtable_len
 //    [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size
 //      The embedded nonstatic oop-map blocks are short pairs (offset, length)
 //      indicating where oops are located in instances of this klass.
 //    [EMBEDDED implementor of the interface] only exist for interface
+//    [EMBEDDED InlineKlassFixedBlock] only if is an InlineKlass instance
 
 
 // forward declaration for class -- see below for definition
 #if INCLUDE_JVMTI
 class BreakpointInfo;
@@ -70,10 +72,11 @@
 class jniIdMapBase;
 class JNIid;
 class JvmtiCachedClassFieldMap;
 class nmethodBucket;
 class OopMapCache;
+class BufferedInlineTypeBlob;
 class InterpreterOopMap;
 class PackageEntry;
 class ModuleEntry;
 
 // This is used in iterators below.
@@ -130,15 +133,34 @@
   uint _count;
 };
 
 struct JvmtiCachedClassFileData;
 
+class SigEntry;
+
+class InlineKlassFixedBlock {
+  Array<SigEntry>** _extended_sig;
+  Array<VMRegPair>** _return_regs;
+  address* _pack_handler;
+  address* _pack_handler_jobject;
+  address* _unpack_handler;
+  int* _default_value_offset;
+  ArrayKlass** _null_free_inline_array_klasses;
+  int _alignment;
+  int _first_field_offset;
+  int _payload_size_in_bytes;
+  int _internal_null_marker_offset; // -1 if none
+
+  friend class InlineKlass;
+};
+
 class InstanceKlass: public Klass {
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class ClassFileParser;
   friend class CompileReplay;
+  friend class TemplateTable;
 
  public:
   static const KlassKind Kind = InstanceKlassKind;
 
  protected:
@@ -169,11 +191,11 @@
   // Annotations for this class
   Annotations*    _annotations;
   // Package this class is defined in
   PackageEntry*   _package_entry;
   // Array classes holding elements of this class.
-  ObjArrayKlass* volatile _array_klasses;
+  ArrayKlass* volatile _array_klasses;
   // Constant pool for this class.
   ConstantPool* _constants;
   // The InnerClasses attribute and EnclosingMethod attribute. The
   // _inner_classes is an array of shorts. If the class has InnerClasses
   // attribute, then the _inner_classes array begins with 4-tuples of shorts
@@ -274,10 +296,15 @@
 
   // Fields information is stored in an UNSIGNED5 encoded stream (see fieldInfo.hpp)
   Array<u1>*          _fieldinfo_stream;
   Array<FieldStatus>* _fields_status;
 
+  Array<InlineKlass*>* _inline_type_field_klasses; // For "inline class" fields, null if none present
+  Array<int>* _null_marker_offsets; // for flat fields with a null marker
+  Array<u2>* _loadable_descriptors;
+  const InlineKlassFixedBlock* _adr_inlineklass_fixed_block;
+
   // embedded Java vtable follows here
   // embedded Java itables follows here
   // embedded static fields follows here
   // embedded nonstatic oop-map blocks follows here
   // embedded implementor of this interface follows here
@@ -327,10 +354,34 @@
   void set_has_nonstatic_fields(bool b)    { _misc_flags.set_has_nonstatic_fields(b); }
 
   bool has_localvariable_table() const     { return _misc_flags.has_localvariable_table(); }
   void set_has_localvariable_table(bool b) { _misc_flags.set_has_localvariable_table(b); }
 
+  bool has_inline_type_fields() const { return _misc_flags.has_inline_type_fields(); }
+  void set_has_inline_type_fields()   { _misc_flags.set_has_inline_type_fields(true); }
+
+  bool is_empty_inline_type() const   { return _misc_flags.is_empty_inline_type(); }
+  void set_is_empty_inline_type()     { _misc_flags.set_is_empty_inline_type(true); }
+
+  // Note:  The naturally_atomic property only applies to
+  // inline classes; it is never true on identity classes.
+  // The bit is placed on instanceKlass for convenience.
+
+  // Query if h/w provides atomic load/store for instances.
+  bool is_naturally_atomic() const  { return _misc_flags.is_naturally_atomic(); }
+  void set_is_naturally_atomic()    { _misc_flags.set_is_naturally_atomic(true); }
+
+  // Query if this class is mentioned in the JVM option ForceNonTearable.
+  // This bit can occur anywhere, but is only significant
+  // for inline classes *and* their super types.
+  // It inherits from supers.
+  bool must_be_atomic() const { return _misc_flags.must_be_atomic(); }
+  void set_must_be_atomic()   { _misc_flags.set_must_be_atomic(true); }
+
+  bool is_implicitly_constructible() const { return _misc_flags.is_implicitly_constructible(); }
+  void set_is_implicitly_constructible()   { _misc_flags.set_is_implicitly_constructible(true); }
+
   // field sizes
   int nonstatic_field_size() const         { return _nonstatic_field_size; }
   void set_nonstatic_field_size(int size)  { _nonstatic_field_size = size; }
 
   int static_field_size() const            { return _static_field_size; }
@@ -342,14 +393,14 @@
   // Java itable
   int  itable_length() const               { return _itable_len; }
   void set_itable_length(int len)          { _itable_len = len; }
 
   // array klasses
-  ObjArrayKlass* array_klasses() const     { return _array_klasses; }
-  inline ObjArrayKlass* array_klasses_acquire() const; // load with acquire semantics
-  inline void release_set_array_klasses(ObjArrayKlass* k); // store with release semantics
-  void set_array_klasses(ObjArrayKlass* k) { _array_klasses = k; }
+  ArrayKlass* array_klasses() const     { return _array_klasses; }
+  inline ArrayKlass* array_klasses_acquire() const; // load with acquire semantics
+  inline void release_set_array_klasses(ArrayKlass* k); // store with release semantics
+  void set_array_klasses(ArrayKlass* k) { _array_klasses = k; }
 
   // methods
   Array<Method*>* methods() const          { return _methods; }
   void set_methods(Array<Method*>* a)      { _methods = a; }
   Method* method_with_idnum(int idnum);
@@ -385,16 +436,20 @@
  private:
   friend class fieldDescriptor;
   FieldInfo field(int index) const;
 
  public:
-  int     field_offset      (int index) const { return field(index).offset(); }
-  int     field_access_flags(int index) const { return field(index).access_flags().as_int(); }
+  int field_offset      (int index) const { return field(index).offset(); }
+  int field_access_flags(int index) const { return field(index).access_flags().as_int(); }
   FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); }
   FieldStatus field_status(int index)   const { return fields_status()->at(index); }
   inline Symbol* field_name        (int index) const;
   inline Symbol* field_signature   (int index) const;
+  bool field_is_flat(int index) const { return field_flags(index).is_flat(); }
+  bool field_has_null_marker(int index) const { return field_flags(index).has_null_marker(); }
+  bool field_is_null_free_inline_type(int index) const;
+  bool is_class_in_loadable_descriptors_attribute(Symbol* name) const;
 
   // Number of Java declared fields
   int java_fields_count() const;
   int total_fields_count() const;
 
@@ -402,10 +457,13 @@
   void set_fieldinfo_stream(Array<u1>* fis) { _fieldinfo_stream = fis; }
 
   Array<FieldStatus>* fields_status() const {return _fields_status; }
   void set_fields_status(Array<FieldStatus>* array) { _fields_status = array; }
 
+  Array<u2>* loadable_descriptors() const { return _loadable_descriptors; }
+  void set_loadable_descriptors(Array<u2>* c) { _loadable_descriptors = c; }
+
   // inner classes
   Array<u2>* inner_classes() const       { return _inner_classes; }
   void set_inner_classes(Array<u2>* f)   { _inner_classes = f; }
 
   // nest members
@@ -541,10 +599,13 @@
 
   // marking
   bool is_marked_dependent() const         { return _misc_flags.is_marked_dependent(); }
   void set_is_marked_dependent(bool value) { _misc_flags.set_is_marked_dependent(value); }
 
+  static ByteSize kind_offset() { return in_ByteSize(offset_of(InstanceKlass, _kind)); }
+  static ByteSize misc_flags_offset() { return in_ByteSize(offset_of(InstanceKlass, _misc_flags)); }
+
   // initialization (virtuals from Klass)
   bool should_be_initialized() const;  // means that initialize should be called
   void initialize(TRAPS);
   void link_class(TRAPS);
   bool link_class_or_fail(TRAPS); // returns false on failure
@@ -873,10 +934,14 @@
   // support for stub routines
   static ByteSize init_state_offset()  { return byte_offset_of(InstanceKlass, _init_state); }
   JFR_ONLY(DEFINE_KLASS_TRACE_ID_OFFSET;)
   static ByteSize init_thread_offset() { return byte_offset_of(InstanceKlass, _init_thread); }
 
+  static ByteSize inline_type_field_klasses_offset() { return in_ByteSize(offset_of(InstanceKlass, _inline_type_field_klasses)); }
+  static ByteSize null_marker_array_offset() { return in_ByteSize(offset_of(InstanceKlass, _null_marker_offsets)); }
+  static ByteSize adr_inlineklass_fixed_block_offset() { return in_ByteSize(offset_of(InstanceKlass, _adr_inlineklass_fixed_block)); }
+
   // subclass/subinterface checks
   bool implements_interface(Klass* k) const;
   bool is_same_or_direct_interface(Klass* k) const;
 
 #ifdef ASSERT
@@ -930,36 +995,51 @@
   // Sizing (in words)
   static int header_size()            { return sizeof(InstanceKlass)/wordSize; }
 
   static int size(int vtable_length, int itable_length,
                   int nonstatic_oop_map_size,
-                  bool is_interface) {
+                  bool is_interface,
+                  bool is_inline_type) {
     return align_metadata_size(header_size() +
            vtable_length +
            itable_length +
            nonstatic_oop_map_size +
-           (is_interface ? (int)sizeof(Klass*)/wordSize : 0));
+           (is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
+           (is_inline_type ? (int)sizeof(InlineKlassFixedBlock) : 0));
   }
 
   int size() const                    { return size(vtable_length(),
                                                itable_length(),
                                                nonstatic_oop_map_size(),
-                                               is_interface());
+                                               is_interface(),
+                                               is_inline_klass());
   }
 
 
   inline intptr_t* start_of_itable() const;
   inline intptr_t* end_of_itable() const;
   inline oop static_field_base_raw();
+  bool bounds_check(address addr, bool edge_ok = false, intptr_t size_in_bytes = -1) const PRODUCT_RETURN0;
 
   inline OopMapBlock* start_of_nonstatic_oop_maps() const;
   inline Klass** end_of_nonstatic_oop_maps() const;
 
   inline InstanceKlass* volatile* adr_implementor() const;
 
+  Array<InlineKlass*>* inline_type_field_klasses_array() const { return _inline_type_field_klasses; }
+  void set_inline_type_field_klasses_array(Array<InlineKlass*>* array) { _inline_type_field_klasses = array; }
+
+  Array<int>* null_marker_offsets_array() const { return _null_marker_offsets; }
+  void set_null_marker_offsets_array(Array<int>* array) { _null_marker_offsets = array; }
+
+  inline InlineKlass* get_inline_type_field_klass(int idx) const;
+  inline InlineKlass* get_inline_type_field_klass_or_null(int idx) const;
+  inline void set_inline_type_field_klass(int idx, InlineKlass* k);
+  inline void reset_inline_type_field_klass(int idx);
+
   // Use this to return the size of an instance in heap words:
-  int size_helper() const {
+  virtual int size_helper() const {
     return layout_helper_to_size_helper(layout_helper());
   }
 
   // This bit is initialized in classFileParser.cpp.
   // It is false under any of the following conditions:
@@ -1007,10 +1087,11 @@
 
   virtual void release_C_heap_structures(bool release_sub_metadata = true);
 
   // Naming
   const char* signature_name() const;
+  const char* signature_name_of_carrier(char c) const;
 
   // Oop fields (and metadata) iterators
   //
   // The InstanceKlass iterators also visits the Object's klass.
 
@@ -1132,11 +1213,11 @@
 #if INCLUDE_CDS
   // CDS support - remove and restore oops from metadata. Oops are not shared.
   virtual void remove_unshareable_info();
   void remove_unshareable_flags();
   virtual void remove_java_mirror();
-  void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS);
+  virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS);
   void init_shared_package_entry();
   bool can_be_verified_at_dumptime() const;
   bool methods_contain_jsr_bytecode() const;
   void compute_has_loops_flag_for_methods();
 #endif
