< prev index next >

src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp

Print this page

 249 // methods with small numbers of arguments without having to shuffle
 250 // the arguments at all. Since we control the java ABI we ought to at
 251 // least get some advantage out of it.
 252 
 253 int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
 254                                            VMRegPair *regs,
 255                                            int total_args_passed) {
 256   // Create the mapping between argument positions and
 257   // registers.
 258   static const Register INT_ArgReg[Argument::n_int_register_parameters_j] = {
 259     j_rarg0, j_rarg1, j_rarg2, j_rarg3,
 260     j_rarg4, j_rarg5, j_rarg6, j_rarg7
 261   };
 262   static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters_j] = {
 263     j_farg0, j_farg1, j_farg2, j_farg3,
 264     j_farg4, j_farg5, j_farg6, j_farg7
 265   };
 266 
 267   uint int_args = 0;
 268   uint fp_args = 0;
 269   uint stk_args = 0; // inc by 2 each time
 270 
 271   for (int i = 0; i < total_args_passed; i++) {
 272     switch (sig_bt[i]) {
 273       case T_BOOLEAN: // fall through
 274       case T_CHAR:    // fall through
 275       case T_BYTE:    // fall through
 276       case T_SHORT:   // fall through
 277       case T_INT:
 278         if (int_args < Argument::n_int_register_parameters_j) {
 279           regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
 280         } else {

 281           regs[i].set1(VMRegImpl::stack2reg(stk_args));
 282           stk_args += 2;
 283         }
 284         break;
 285       case T_VOID:
 286         // halves of T_LONG or T_DOUBLE
 287         assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
 288         regs[i].set_bad();
 289         break;
 290       case T_LONG:      // fall through
 291         assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 292       case T_OBJECT:    // fall through
 293       case T_ARRAY:     // fall through
 294       case T_ADDRESS:
 295         if (int_args < Argument::n_int_register_parameters_j) {
 296           regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
 297         } else {

 298           regs[i].set2(VMRegImpl::stack2reg(stk_args));
 299           stk_args += 2;
 300         }
 301         break;
 302       case T_FLOAT:
 303         if (fp_args < Argument::n_float_register_parameters_j) {
 304           regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
 305         } else {

 306           regs[i].set1(VMRegImpl::stack2reg(stk_args));
 307           stk_args += 2;
 308         }
 309         break;
 310       case T_DOUBLE:
 311         assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 312         if (fp_args < Argument::n_float_register_parameters_j) {
 313           regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
 314         } else {

 315           regs[i].set2(VMRegImpl::stack2reg(stk_args));
 316           stk_args += 2;
 317         }
 318         break;
 319       default:
 320         ShouldNotReachHere();
 321     }
 322   }
 323 
 324   return align_up(stk_args, 2);
 325 }
 326 
 327 // Patch the callers callsite with entry to compiled code if it exists.
 328 static void patch_callers_callsite(MacroAssembler *masm) {
 329   Label L;
 330   __ ld(t0, Address(xmethod, in_bytes(Method::code_offset())));
 331   __ beqz(t0, L);
 332 
 333   __ enter();
 334   __ push_CPU_state();
 335 
 336   // VM needs caller's callsite
 337   // VM needs target method
 338   // This needs to be a long call since we will relocate this adapter to
 339   // the codeBuffer and it may not reach
 340 
 341 #ifndef PRODUCT
 342   assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area");
 343 #endif
 344 

 249 // methods with small numbers of arguments without having to shuffle
 250 // the arguments at all. Since we control the java ABI we ought to at
 251 // least get some advantage out of it.
 252 
 253 int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
 254                                            VMRegPair *regs,
 255                                            int total_args_passed) {
 256   // Create the mapping between argument positions and
 257   // registers.
 258   static const Register INT_ArgReg[Argument::n_int_register_parameters_j] = {
 259     j_rarg0, j_rarg1, j_rarg2, j_rarg3,
 260     j_rarg4, j_rarg5, j_rarg6, j_rarg7
 261   };
 262   static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters_j] = {
 263     j_farg0, j_farg1, j_farg2, j_farg3,
 264     j_farg4, j_farg5, j_farg6, j_farg7
 265   };
 266 
 267   uint int_args = 0;
 268   uint fp_args = 0;
 269   uint stk_args = 0;
 270 
 271   for (int i = 0; i < total_args_passed; i++) {
 272     switch (sig_bt[i]) {
 273       case T_BOOLEAN: // fall through
 274       case T_CHAR:    // fall through
 275       case T_BYTE:    // fall through
 276       case T_SHORT:   // fall through
 277       case T_INT:
 278         if (int_args < Argument::n_int_register_parameters_j) {
 279           regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
 280         } else {
 281           stk_args = align_up(stk_args, 2);
 282           regs[i].set1(VMRegImpl::stack2reg(stk_args));
 283           stk_args += 1;
 284         }
 285         break;
 286       case T_VOID:
 287         // halves of T_LONG or T_DOUBLE
 288         assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
 289         regs[i].set_bad();
 290         break;
 291       case T_LONG:      // fall through
 292         assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 293       case T_OBJECT:    // fall through
 294       case T_ARRAY:     // fall through
 295       case T_ADDRESS:
 296         if (int_args < Argument::n_int_register_parameters_j) {
 297           regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
 298         } else {
 299           stk_args = align_up(stk_args, 2);
 300           regs[i].set2(VMRegImpl::stack2reg(stk_args));
 301           stk_args += 2;
 302         }
 303         break;
 304       case T_FLOAT:
 305         if (fp_args < Argument::n_float_register_parameters_j) {
 306           regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
 307         } else {
 308           stk_args = align_up(stk_args, 2);
 309           regs[i].set1(VMRegImpl::stack2reg(stk_args));
 310           stk_args += 1;
 311         }
 312         break;
 313       case T_DOUBLE:
 314         assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 315         if (fp_args < Argument::n_float_register_parameters_j) {
 316           regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
 317         } else {
 318           stk_args = align_up(stk_args, 2);
 319           regs[i].set2(VMRegImpl::stack2reg(stk_args));
 320           stk_args += 2;
 321         }
 322         break;
 323       default:
 324         ShouldNotReachHere();
 325     }
 326   }
 327 
 328   return stk_args;
 329 }
 330 
 331 // Patch the callers callsite with entry to compiled code if it exists.
 332 static void patch_callers_callsite(MacroAssembler *masm) {
 333   Label L;
 334   __ ld(t0, Address(xmethod, in_bytes(Method::code_offset())));
 335   __ beqz(t0, L);
 336 
 337   __ enter();
 338   __ push_CPU_state();
 339 
 340   // VM needs caller's callsite
 341   // VM needs target method
 342   // This needs to be a long call since we will relocate this adapter to
 343   // the codeBuffer and it may not reach
 344 
 345 #ifndef PRODUCT
 346   assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area");
 347 #endif
 348 
< prev index next >