< prev index next >

src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp

Print this page
@@ -664,11 +664,12 @@
            __ set_info("fast new_instance init check", dont_gc_arguments);
          }
  
          __ enter();
          OopMap* map = save_live_registers(sasm);
-         int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
+         int call_offset;
+         call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
          oop_maps = new OopMapSet();
          oop_maps->add_gc_map(call_offset, map);
          restore_live_registers_except_r0(sasm);
          __ verify_oop(obj);
          __ leave();

@@ -697,47 +698,68 @@
        }
        break;
  
      case C1StubId::new_type_array_id:
      case C1StubId::new_object_array_id:
+     case C1StubId::new_null_free_array_id:
        {
          Register length   = r19; // Incoming
          Register klass    = r3; // Incoming
          Register obj      = r0; // Result
  
          if (id == C1StubId::new_type_array_id) {
            __ set_info("new_type_array", dont_gc_arguments);
-         } else {
+         } else if (id == C1StubId::new_object_array_id) {
            __ set_info("new_object_array", dont_gc_arguments);
+         } else {
+           __ set_info("new_null_free_array", dont_gc_arguments);
          }
  
  #ifdef ASSERT
          // assert object type is really an array of the proper kind
          {
            Label ok;
            Register t0 = obj;
            __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
            __ asrw(t0, t0, Klass::_lh_array_tag_shift);
-           int tag = ((id == C1StubId::new_type_array_id)
-                      ? Klass::_lh_array_tag_type_value
-                      : Klass::_lh_array_tag_obj_value);
-           __ mov(rscratch1, tag);
-           __ cmpw(t0, rscratch1);
-           __ br(Assembler::EQ, ok);
-           __ stop("assert(is an array klass)");
+           switch (id) {
+           case C1StubId::new_type_array_id:
+             __ cmpw(t0, Klass::_lh_array_tag_type_value);
+             __ br(Assembler::EQ, ok);
+             __ stop("assert(is a type array klass)");
+             break;
+           case C1StubId::new_object_array_id:
+             __ cmpw(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
+             __ br(Assembler::EQ, ok);
+             __ cmpw(t0, Klass::_lh_array_tag_vt_value);  // new "[LVT;"
+             __ br(Assembler::EQ, ok);
+             __ stop("assert(is an object or inline type array klass)");
+             break;
+           case C1StubId::new_null_free_array_id:
+             __ cmpw(t0, Klass::_lh_array_tag_vt_value);  // the array can be a flat array.
+             __ br(Assembler::EQ, ok);
+             __ cmpw(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
+             __ br(Assembler::EQ, ok);
+             __ stop("assert(is an object or inline type array klass)");
+             break;
+           default:  ShouldNotReachHere();
+           }
            __ should_not_reach_here();
            __ bind(ok);
          }
  #endif // ASSERT
  
          __ enter();
          OopMap* map = save_live_registers(sasm);
          int call_offset;
          if (id == C1StubId::new_type_array_id) {
            call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
-         } else {
+         } else if (id == C1StubId::new_object_array_id) {
            call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
+         } else {
+           assert(id == C1StubId::new_null_free_array_id, "must be");
+           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
          }
  
          oop_maps = new OopMapSet();
          oop_maps->add_gc_map(call_offset, map);
          restore_live_registers_except_r0(sasm);

@@ -768,10 +790,96 @@
          // r0,: new multi array
          __ verify_oop(r0);
        }
        break;
  
+     case C1StubId::buffer_inline_args_id:
+     case C1StubId::buffer_inline_args_no_receiver_id:
+       {
+         const char* name = (id == C1StubId::buffer_inline_args_id) ?
+           "buffer_inline_args" : "buffer_inline_args_no_receiver";
+         StubFrame f(sasm, name, dont_gc_arguments);
+         OopMap* map = save_live_registers(sasm);
+         Register method = r19;   // Incoming
+         address entry = (id == C1StubId::buffer_inline_args_id) ?
+           CAST_FROM_FN_PTR(address, buffer_inline_args) :
+           CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
+         // This is called from a C1 method's scalarized entry point
+         // where r0-r7 may be holding live argument values so we can't
+         // return the result in r0 as the other stubs do. LR is used as
+         // a temporay below to avoid the result being clobbered by
+         // restore_live_registers.
+         int call_offset = __ call_RT(lr, noreg, entry, method);
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers(sasm);
+         __ mov(r20, lr);
+         __ verify_oop(r20);  // r20: an array of buffered value objects
+      }
+      break;
+ 
+     case C1StubId::load_flat_array_id:
+       {
+         StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
+         OopMap* map = save_live_registers(sasm);
+ 
+         // Called with store_parameter and not C abi
+ 
+         f.load_argument(1, r0); // r0,: array
+         f.load_argument(0, r1); // r1,: index
+         int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, load_flat_array), r0, r1);
+ 
+         // Ensure the stores that initialize the buffer are visible
+         // before any subsequent store that publishes this reference.
+         __ membar(Assembler::StoreStore);
+ 
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers_except_r0(sasm);
+ 
+         // r0: loaded element at array[index]
+         __ verify_oop(r0);
+       }
+       break;
+ 
+     case C1StubId::store_flat_array_id:
+       {
+         StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
+         OopMap* map = save_live_registers(sasm, 4);
+ 
+         // Called with store_parameter and not C abi
+ 
+         f.load_argument(2, r0); // r0: array
+         f.load_argument(1, r1); // r1: index
+         f.load_argument(0, r2); // r2: value
+         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), r0, r1, r2);
+ 
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers_except_r0(sasm);
+       }
+       break;
+ 
+     case C1StubId::substitutability_check_id:
+       {
+         StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
+         OopMap* map = save_live_registers(sasm);
+ 
+         // Called with store_parameter and not C abi
+ 
+         f.load_argument(1, r1); // r1,: left
+         f.load_argument(0, r2); // r2,: right
+         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), r1, r2);
+ 
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers_except_r0(sasm);
+ 
+         // r0,: are the two operands substitutable
+       }
+       break;
+ 
      case C1StubId::register_finalizer_id:
        {
          __ set_info("register_finalizer", dont_gc_arguments);
  
          // This is called via call_runtime so the arguments

@@ -807,15 +915,27 @@
          oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
        }
        break;
  
      case C1StubId::throw_incompatible_class_change_error_id:
-       { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments, does_not_return);
+       { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments, does_not_return);
          oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
        }
        break;
  
+     case C1StubId::throw_illegal_monitor_state_exception_id:
+       { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
+         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
+       }
+       break;
+ 
+     case C1StubId::throw_identity_exception_id:
+       { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
+         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
+       }
+       break;
+ 
      case C1StubId::slow_subtype_check_id:
        {
          // Typical calling sequence:
          // __ push(klass_RInfo);  // object klass or other subclass
          // __ push(sup_k_RInfo);  // array element klass or other superclass

@@ -1015,17 +1135,21 @@
          restore_live_registers(sasm);
        }
        break;
  
      default:
+       // FIXME: For unhandled trap_id this code fails with assert during vm intialization
+       // rather than insert a call to unimplemented_entry
        { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
          __ mov(r0, (int)id);
          __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
        }
        break;
      }
    }
+ 
+ 
    return oop_maps;
  }
  
  #undef __
  
< prev index next >