< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Print this page
@@ -27,11 +27,16 @@
  #define CPU_AARCH64_MACROASSEMBLER_AARCH64_HPP
  
  #include "asm/assembler.inline.hpp"
  #include "oops/compressedOops.hpp"
  #include "runtime/vm_version.hpp"
+ #include "utilities/macros.hpp"
  #include "utilities/powerOfTwo.hpp"
+ #include "runtime/signature.hpp"
+ 
+ 
+ class ciInlineKlass;
  
  // MacroAssembler extends Assembler by frequently used macros.
  //
  // Instructions for which a 'better' code sequence exists depending
  // on arguments should also go in here.

@@ -597,10 +602,41 @@
  
    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_inlined(Register flags, Register temp_reg, Label& is_flattened);
+ 
+   // Check oops for special arrays, i.e. flattened and/or null-free
+   void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
+   void test_flattened_array_oop(Register klass, Register temp_reg, Label& is_flattened_array);
+   void test_non_flattened_array_oop(Register oop, Register temp_reg, Label&is_non_flattened_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 flatten or null-free arrays...
+   void test_flattened_array_layout(Register lh, Label& is_flattened_array);
+   void test_non_flattened_array_layout(Register lh, Label& is_non_flattened_array);
+   void test_null_free_array_layout(Register lh, Label& is_null_free_array);
+   void test_non_null_free_array_layout(Register lh, Label& is_non_null_free_array);
+ 
    static address target_addr_for_insn(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);
    }

@@ -804,10 +840,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 tmp);

@@ -816,25 +854,36 @@
  
    void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
                        Register tmp1, Register tmp_thread);
  
    void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
-                        Register tmp1, Register tmp_thread);
+                        Register tmp1, Register tmp_thread, Register tmp3 = noreg);
+ 
+   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 = noreg,
                       Register thread_tmp = noreg, DecoratorSet decorators = 0);
  
    void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
                                Register thread_tmp = noreg, DecoratorSet decorators = 0);
    void store_heap_oop(Address dst, Register src, Register tmp1 = noreg,
-                       Register tmp_thread = noreg, DecoratorSet decorators = 0);
+                       Register tmp_thread = noreg, Register tmp3 = noreg, DecoratorSet decorators = 0);
  
    // 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

@@ -871,10 +920,19 @@
  
    // Round up to a power of two
    void round_to(Register reg, int modulus);
  
    // 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 eden_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

@@ -888,10 +946,13 @@
      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,

@@ -1176,10 +1237,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);

@@ -1240,10 +1319,12 @@
  
    void string_equals(Register a1, Register a2, Register result, Register cnt1,
                       int elem_size);
  
    void fill_words(Register base, Register cnt, Register value);
+   void fill_words(Register base, uint64_t cnt, Register value);
+ 
    void 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;
< prev index next >