diff a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
@@ -30,11 +30,16 @@
 #include "code/vmreg.hpp"
 #include "metaprogramming/enableIf.hpp"
 #include "oops/compressedOops.hpp"
 #include "oops/compressedKlass.hpp"
 #include "runtime/vm_version.hpp"
+#include "utilities/macros.hpp"
 #include "utilities/powerOfTwo.hpp"
+#include "runtime/signature.hpp"
+
+
+class ciInlineKlass;
 
 class OopMap;
 
 // MacroAssembler extends Assembler by frequently used macros.
 //
@@ -625,10 +630,40 @@
 
   virtual void null_check(Register reg, int offset = -1);
   static bool needs_explicit_null_check(intptr_t offset);
   static bool uses_implicit_null_check(void* address);
 
+  // markWord tests, kills markWord reg
+  void test_markword_is_inline_type(Register markword, Label& is_inline_type);
+
+  // inlineKlass queries, kills temp_reg
+  void test_klass_is_inline_type(Register klass, Register temp_reg, Label& is_inline_type);
+  void test_klass_is_empty_inline_type(Register klass, Register temp_reg, Label& is_empty_inline_type);
+  void test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type);
+
+  // Get the default value oop for the given InlineKlass
+  void get_default_value_oop(Register inline_klass, Register temp_reg, Register obj);
+  // The empty value oop, for the given InlineKlass ("empty" as in no instance fields)
+  // get_default_value_oop with extra assertion for empty inline klass
+  void get_empty_inline_type_oop(Register inline_klass, Register temp_reg, Register obj);
+
+  void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
+  void test_field_is_not_null_free_inline_type(Register flags, Register temp_reg, Label& not_null_free);
+  void test_field_is_flat(Register flags, Register temp_reg, Label& is_flat);
+  void test_field_has_null_marker(Register flags, Register temp_reg, Label& has_null_marker);
+
+  // Check oops for special arrays, i.e. flat arrays and/or null-free arrays
+  void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
+  void test_flat_array_oop(Register klass, Register temp_reg, Label& is_flat_array);
+  void test_non_flat_array_oop(Register oop, Register temp_reg, Label&is_non_flat_array);
+  void test_null_free_array_oop(Register oop, Register temp_reg, Label& is_null_free_array);
+  void test_non_null_free_array_oop(Register oop, Register temp_reg, Label&is_non_null_free_array);
+
+  // Check array klass layout helper for flat or null-free arrays...
+  void test_flat_array_layout(Register lh, Label& is_flat_array);
+  void test_non_flat_array_layout(Register lh, Label& is_non_flat_array);
+
   static address target_addr_for_insn(address insn_addr, unsigned insn);
   static address target_addr_for_insn_or_null(address insn_addr, unsigned insn);
   static address target_addr_for_insn(address insn_addr) {
     unsigned insn = *(unsigned*)insn_addr;
     return target_addr_for_insn(insn_addr, insn);
@@ -862,10 +897,12 @@
 
   void load_method_holder_cld(Register rresult, Register rmethod);
   void load_method_holder(Register holder, Register method);
 
   // oop manipulations
+  void load_metadata(Register dst, Register src);
+
   void load_klass(Register dst, Register src);
   void store_klass(Register dst, Register src);
   void cmp_klass(Register oop, Register trial_klass, Register tmp);
 
   void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
@@ -876,10 +913,19 @@
                       Register tmp1, Register tmp2);
 
   void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
                        Register tmp1, Register tmp2, Register tmp3);
 
+  void access_value_copy(DecoratorSet decorators, Register src, Register dst, Register inline_klass);
+
+  // inline type data payload offsets...
+  void first_field_offset(Register inline_klass, Register offset);
+  void data_for_oop(Register oop, Register data, Register inline_klass);
+  // get data payload ptr a flat value array at index, kills rcx and index
+  void data_for_value_array_index(Register array, Register array_klass,
+                                  Register index, Register data);
+
   void load_heap_oop(Register dst, Address src, Register tmp1,
                      Register tmp2, DecoratorSet decorators = 0);
 
   void load_heap_oop_not_null(Register dst, Address src, Register tmp1,
                               Register tmp2, DecoratorSet decorators = 0);
@@ -889,10 +935,12 @@
   // currently unimplemented
   // Used for storing null. All other oop constants should be
   // stored using routines that take a jobject.
   void store_heap_oop_null(Address dst);
 
+  void load_prototype_header(Register dst, Register src);
+
   void store_klass_gap(Register dst, Register src);
 
   // This dummy is to prevent a call to store_heap_oop from
   // converting a zero (like null) into a Register by giving
   // the compiler two choices it can't resolve
@@ -936,20 +984,32 @@
   // java.lang.Math::round intrinsics
   void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
   void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
 
   // allocation
+
+  // Object / value buffer allocation...
+  // Allocate instance of klass, assumes klass initialized by caller
+  // new_obj prefers to be rax
+  // Kills t1 and t2, perserves klass, return allocation in new_obj (rsi on LP64)
+  void allocate_instance(Register klass, Register new_obj,
+                         Register t1, Register t2,
+                         bool clear_fields, Label& alloc_failed);
+
   void tlab_allocate(
     Register obj,                      // result: pointer to object after successful allocation
     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
     int      con_size_in_bytes,        // object size in bytes if   known at compile time
     Register t1,                       // temp register
     Register t2,                       // temp register
     Label&   slow_case                 // continuation point if fast allocation fails
   );
   void verify_tlab();
 
+  // For field "index" within "klass", return inline_klass ...
+  void get_inline_type_field_klass(Register klass, Register index, Register inline_klass);
+
   // interface method calling
   void lookup_interface_method(Register recv_klass,
                                Register intf_klass,
                                RegisterOrConstant itable_index,
                                Register method_result,
@@ -1340,10 +1400,28 @@
   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
 
   void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
 
+  void verified_entry(Compile* C, int sp_inc);
+
+  // Inline type specific methods
+  #include "asm/macroAssembler_common.hpp"
+
+  int store_inline_type_fields_to_buf(ciInlineKlass* vk, bool from_interpreter = true);
+  bool move_helper(VMReg from, VMReg to, BasicType bt, RegState reg_state[]);
+  bool unpack_inline_helper(const GrowableArray<SigEntry>* sig, int& sig_index,
+                            VMReg from, int& from_index, VMRegPair* to, int to_count, int& to_index,
+                            RegState reg_state[]);
+  bool pack_inline_helper(const GrowableArray<SigEntry>* sig, int& sig_index, int vtarg_index,
+                          VMRegPair* from, int from_count, int& from_index, VMReg to,
+                          RegState reg_state[], Register val_array);
+  int extend_stack_for_inline_args(int args_on_stack);
+  void remove_frame(int initial_framesize, bool needs_stack_repair);
+  VMReg spill_reg_for(VMReg reg);
+  void save_stack_increment(int sp_inc, int frame_size);
+
   void tableswitch(Register index, jint lowbound, jint highbound,
                    Label &jumptable, Label &jumptable_end, int stride = 1) {
     adr(rscratch1, jumptable);
     subsw(rscratch2, index, lowbound);
     subsw(zr, rscratch2, highbound - lowbound);
@@ -1403,10 +1481,12 @@
                         Register tmp1, Register tmp2, Register tmp3, int elem_size);
 
   void string_equals(Register a1, Register a2, Register result, Register cnt1);
 
   void fill_words(Register base, Register cnt, Register value);
+  void fill_words(Register base, uint64_t cnt, Register value);
+
   address zero_words(Register base, uint64_t cnt);
   address zero_words(Register ptr, Register cnt);
   void zero_dcache_blocks(Register base, Register cnt);
 
   static const int zero_words_block_size;
