< prev index next >

src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
   * Copyright (c) 2014, Red Hat Inc. All rights reserved.
   * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. 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

@@ -733,32 +733,56 @@
        }
        break;
  
      case StubId::c1_new_type_array_id:
      case StubId::c1_new_object_array_id:
+     case StubId::c1_new_null_free_array_id:
        {
          Register length   = x9;  // Incoming
          Register klass    = x13; // Incoming
          Register obj      = x10; // Result
  
          if (id == StubId::c1_new_type_array_id) {
            __ set_info("new_type_array", dont_gc_arguments);
-         } else {
+         } else if (id == StubId::c1_new_object_array_id) {
            __ set_info("new_object_array", dont_gc_arguments);
+         } else {
+           assert(id == StubId::c1_new_null_free_array_id, "must be");
+           __ 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 tmp = obj;
            __ lwu(tmp, Address(klass, Klass::layout_helper_offset()));
            __ sraiw(tmp, tmp, Klass::_lh_array_tag_shift);
-           int tag = ((id == StubId::c1_new_type_array_id) ? Klass::_lh_array_tag_type_value : Klass::_lh_array_tag_obj_value);
-           __ mv(t0, tag);
-           __ beq(t0, tmp, ok);
-           __ stop("assert(is an array klass)");
+ 
+           switch (id) {
+             case StubId::c1_new_type_array_id:
+               __ mv(t0, (int)Klass::_lh_array_tag_type_value);
+               __ beq(t0, tmp, ok);
+               __ stop("assert(is a type array klass)");
+               break;
+             case StubId::c1_new_object_array_id:
+               __ mv(t0, (int)Klass::_lh_array_tag_ref_value);  // new "[Ljava/lang/Object;"
+               __ beq(t0, tmp, ok);
+               __ mv(t0, (int)Klass::_lh_array_tag_flat_value); // new "[LVT;"
+               __ beq(t0, tmp, ok);
+               __ stop("assert(is an object or inline type array klass)");
+               break;
+             case StubId::c1_new_null_free_array_id:
+               __ mv(t0, (int)Klass::_lh_array_tag_flat_value); // the array can be a flat array.
+               __ beq(t0, tmp, ok);
+               __ mv(t0, (int)Klass::_lh_array_tag_ref_value);  // the array cannot be a flat array (due to the InlineArrayElementMaxFlatSize, etc.)
+               __ beq(t0, tmp, ok);
+               __ stop("assert(is an object or inline type array klass)");
+               break;
+             default: ShouldNotReachHere();
+          }
+ 
            __ should_not_reach_here();
            __ bind(ok);
          }
  #endif // ASSERT
  

@@ -766,12 +790,14 @@
          OopMap* map = save_live_registers(sasm);
          assert_cond(map != nullptr);
          int call_offset = 0;
          if (id == StubId::c1_new_type_array_id) {
            call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
-         } else {
+         } else if (id == StubId::c1_new_object_array_id) {
            call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
+         } else {
+           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
          }
  
          oop_maps = new OopMapSet();
          assert_cond(oop_maps != nullptr);
          oop_maps->add_gc_map(call_offset, map);

@@ -806,10 +832,97 @@
          // x10: new multi array
          __ verify_oop(x10);
        }
        break;
  
+     case StubId::c1_buffer_inline_args_id:
+     case StubId::c1_buffer_inline_args_no_receiver_id:
+       {
+         const char* name = (id == StubId::c1_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 = x9;   // Incoming
+         address entry = (id == StubId::c1_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 x10-x17 may be holding live argument values so we can't
+         // return the result in x10 as the other stubs do. RA is used as
+         // a temporary below to avoid the result being clobbered by
+         // restore_live_registers. It's saved and restored by
+         // StubAssembler::prologue and epilogue anyway.
+         int call_offset = __ call_RT(ra, noreg, entry, method);
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers(sasm);
+         __ mv(x18, ra);
+         __ verify_oop(x18);  // x18: an array of buffered value objects
+       }
+       break;
+ 
+     case StubId::c1_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, x10); // x10,: array
+         f.load_argument(0, x11); // x11,: index
+         int call_offset = __ call_RT(x10, noreg, CAST_FROM_FN_PTR(address, load_flat_array), x10, x11);
+ 
+         // Ensure the stores that initialize the buffer are visible
+         // before many subsequent store that publishes this reference.
+         __ membar(MacroAssembler::StoreStore);
+ 
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers_except_r10(sasm);
+ 
+         // x10: loaded element at array[index]
+         __ verify_oop(x10);
+       }
+       break;
+ 
+     case StubId::c1_store_flat_array_id:
+       {
+         StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
+         OopMap* map = save_live_registers(sasm);
+ 
+         // Called with store_parameter and not C abi
+ 
+         f.load_argument(2, x10); // x10: array
+         f.load_argument(1, x11); // x11: index
+         f.load_argument(0, x12); // x12: value
+         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), x10, x11, x12);
+ 
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers_except_r10(sasm);
+       }
+       break;
+ 
+     case StubId::c1_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, x11); // x11,: left
+         f.load_argument(0, x12); // x12,: right
+         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), x11, x12);
+ 
+         oop_maps = new OopMapSet();
+         oop_maps->add_gc_map(call_offset, map);
+         restore_live_registers_except_r10(sasm);
+ 
+         // x10,: are the two operands substitutable
+       }
+       break;
+ 
      case StubId::c1_register_finalizer_id:
        {
          __ set_info("register_finalizer", dont_gc_arguments);
  
          // This is called via call_runtime so the arguments

@@ -849,16 +962,28 @@
        }
        break;
  
      case StubId::c1_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 StubId::c1_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 StubId::c1_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 StubId::c1_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)
< prev index next >