< prev index next >

src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

Print this page




 335   // r1, r2 used to address klasses and states, exclude it from return convention to avoid colision 
 336 
 337   static const Register INT_ArgReg[java_return_convention_max_int] = {
 338      r0 /* j_rarg7 */, j_rarg6, j_rarg5, j_rarg4, j_rarg3, j_rarg2
 339   };
 340 
 341   static const FloatRegister FP_ArgReg[java_return_convention_max_float] = {
 342     j_farg0, j_farg1, j_farg2, j_farg3, j_farg4, j_farg5, j_farg6, j_farg7
 343   };
 344 
 345   uint int_args = 0;
 346   uint fp_args = 0;
 347 
 348   for (int i = 0; i < total_args_passed; i++) {
 349     switch (sig_bt[i]) {
 350     case T_BOOLEAN:
 351     case T_CHAR:
 352     case T_BYTE:
 353     case T_SHORT:
 354     case T_INT:
 355       if (int_args < Argument::n_int_register_parameters_j) {
 356         regs[i].set1(INT_ArgReg[int_args]->as_VMReg());
 357         int_args ++;
 358       } else {
 359         // Should we have gurantee here?
 360         return -1;
 361       }
 362       break;
 363     case T_VOID:
 364       // halves of T_LONG or T_DOUBLE
 365       assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
 366       regs[i].set_bad();
 367       break;
 368     case T_LONG:
 369       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 370       // fall through
 371     case T_OBJECT:
 372     case T_ARRAY:
 373     case T_ADDRESS:
 374       // Should T_METADATA be added to java_calling_convention as well ?
 375     case T_METADATA:
 376     case T_VALUETYPE:
 377       if (int_args < Argument::n_int_register_parameters_j) {
 378         regs[i].set2(INT_ArgReg[int_args]->as_VMReg());
 379         int_args ++;
 380       } else {
 381         return -1;
 382       }
 383       break;
 384     case T_FLOAT:
 385       if (fp_args < Argument::n_float_register_parameters_j) {
 386         regs[i].set1(FP_ArgReg[fp_args]->as_VMReg());
 387         fp_args ++;
 388       } else {
 389         return -1;
 390       }
 391       break;
 392     case T_DOUBLE:
 393       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 394       if (fp_args < Argument::n_float_register_parameters_j) {
 395         regs[i].set2(FP_ArgReg[fp_args]->as_VMReg());
 396         fp_args ++;
 397       } else {
 398         return -1;
 399       }
 400       break;
 401     default:
 402       ShouldNotReachHere();
 403       break;
 404     }
 405   }


 426 #endif
 427 
 428   __ mov(c_rarg0, rmethod);
 429   __ mov(c_rarg1, lr);
 430   __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)));
 431   __ blrt(rscratch1, 2, 0, 0);
 432   __ maybe_isb();
 433 
 434   __ pop_CPU_state();
 435   // restore sp
 436   __ leave();
 437   __ bind(L);
 438 }
 439 
 440 // For each value type argument, sig includes the list of fields of
 441 // the value type. This utility function computes the number of
 442 // arguments for the call if value types are passed by reference (the
 443 // calling convention the interpreter expects).
 444 static int compute_total_args_passed_int(const GrowableArray<SigEntry>* sig_extended) {
 445  int total_args_passed = 0;


































 446  total_args_passed = sig_extended->length();


 447  return total_args_passed;
 448 }
 449 
 450 
 451 static void gen_c2i_adapter_helper(MacroAssembler* masm, BasicType bt, const VMRegPair& reg_pair, int extraspace, const Address& to) {
 452 


 453     // Say 4 args:
 454     // i   st_off
 455     // 0   32 T_LONG
 456     // 1   24 T_VOID
 457     // 2   16 T_OBJECT
 458     // 3    8 T_BOOL
 459     // -    0 return address
 460     //
 461     // However to make thing extra confusing. Because we can fit a long/double in
 462     // a single slot on a 64 bt vm and it would be silly to break them up, the interpreter
 463     // leaves one slot empty and only stores to a single slot. In this case the
 464     // slot that is occupied is the T_VOID slot. See I said it was confusing.
 465 
 466     // int next_off = st_off - Interpreter::stackElementSize;
 467 
 468     VMReg r_1 = reg_pair.first();
 469     VMReg r_2 = reg_pair.second();
 470 
 471     if (!r_1->is_valid()) {
 472       assert(!r_2->is_valid(), "");
 473       return;
 474     }
 475 
 476     if (r_1->is_stack()) {
 477       // memory to memory use rscratch1
 478       // DMS CHECK: words_pushed is always 0 and can be removed?
 479       // int ld_off = (r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace + words_pushed * wordSize);
 480       int ld_off = (r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace);
 481       if (!r_2->is_valid()) {
 482         // sign extend??
 483         __ ldrw(rscratch1, Address(sp, ld_off));
 484         __ str(rscratch1, to);
 485 
 486       } else {
 487         __ ldr(rscratch1, Address(sp, ld_off));
 488         __ str(rscratch1, to);
 489       }
 490     } else if (r_1->is_Register()) {
 491       Register r = r_1->as_Register(); 
 492       __ str(r, to);
 493     } else {
 494       assert(r_1->is_FloatRegister(), "");
 495       if (!r_2->is_valid()) {
 496         // only a float use just part of the slot
 497         __ strs(r_1->as_FloatRegister(), to);
 498       } else {
 499         __ strd(r_1->as_FloatRegister(), to);
 500       }


 504 static void gen_c2i_adapter(MacroAssembler *masm,
 505                             const GrowableArray<SigEntry>* sig_extended,
 506                             const VMRegPair *regs,
 507                             Label& skip_fixup,
 508                             address start,
 509                             OopMapSet* oop_maps,
 510                             int& frame_complete,
 511                             int& frame_size_in_words,
 512                             bool alloc_value_receiver) {
 513 
 514   // Before we get into the guts of the C2I adapter, see if we should be here
 515   // at all.  We've come from compiled code and are attempting to jump to the
 516   // interpreter, which means the caller made a static call to get here
 517   // (vcalls always get a compiled target if there is one).  Check for a
 518   // compiled target.  If there is one, we need to patch the caller's call.
 519   patch_callers_callsite(masm);
 520 
 521   __ bind(skip_fixup);
 522 
 523   bool has_value_argument = false;













































 524   int words_pushed = 0;
 525 
 526   // Since all args are passed on the stack, total_args_passed *
 527   // Interpreter::stackElementSize is the space we need.
 528 
 529   int total_args_passed = compute_total_args_passed_int(sig_extended);
 530   int extraspace = (total_args_passed * Interpreter::stackElementSize) + wordSize;
 531 
 532   // stack is aligned, keep it that way
 533   extraspace = align_up(extraspace, 2 * wordSize);
 534 
 535   __ mov(r13, sp);
 536 
 537   if (extraspace)
 538     __ sub(sp, sp, extraspace);
 539 
 540   // Now write the args into the outgoing interpreter space
 541 
 542   int ignored = 0, next_vt_arg = 0, next_arg_int = 0;
 543   bool has_oop_field = false;
 544 
 545   for (int next_arg_comp = 0; next_arg_comp < total_args_passed; next_arg_comp++) {
 546     BasicType bt = sig_extended->at(next_arg_comp)._bt;
 547     // offset to start parameters
 548     int st_off   = (total_args_passed - next_arg_int - 1) * Interpreter::stackElementSize;
 549 


 550     if (SigEntry::is_reserved_entry(sig_extended, next_arg_comp)) {
 551        continue; // Ignore reserved entry
 552     }
 553 
 554      if (bt == T_VOID) { 
 555        assert(next_arg_comp > 0 && (sig_extended->at(next_arg_comp - 1)._bt == T_LONG || sig_extended->at(next_arg_comp - 1)._bt == T_DOUBLE), "missing half");
 556        next_arg_int ++;
 557        continue;
 558      }
 559 
 560      int next_off = st_off - Interpreter::stackElementSize;
 561      int offset = (bt == T_LONG || bt == T_DOUBLE) ? next_off : st_off;
 562 
 563      gen_c2i_adapter_helper(masm, bt, regs[next_arg_comp], extraspace, Address(sp, offset)); 
 564      next_arg_int ++;








































 565   }
 566 
 567 // If a value type was allocated and initialized, apply post barrier to all oop fields
 568   if (has_value_argument && has_oop_field) {
 569     __ push(r13); // save senderSP
 570     __ push(r1); // save callee
 571     // Allocate argument register save area
 572     if (frame::arg_reg_save_area_bytes != 0) {
 573       __ sub(sp, sp, frame::arg_reg_save_area_bytes);
 574     }
 575     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::apply_post_barriers), rthread, r10);
 576     // De-allocate argument register save area
 577     if (frame::arg_reg_save_area_bytes != 0) {
 578       __ add(sp, sp, frame::arg_reg_save_area_bytes);
 579     }
 580     __ pop(r1); // restore callee
 581     __ pop(r13); // restore sender SP
 582   }
 583 
 584   __ mov(esp, sp); // Interp expects args on caller's expression stack




 335   // r1, r2 used to address klasses and states, exclude it from return convention to avoid colision 
 336 
 337   static const Register INT_ArgReg[java_return_convention_max_int] = {
 338      r0 /* j_rarg7 */, j_rarg6, j_rarg5, j_rarg4, j_rarg3, j_rarg2
 339   };
 340 
 341   static const FloatRegister FP_ArgReg[java_return_convention_max_float] = {
 342     j_farg0, j_farg1, j_farg2, j_farg3, j_farg4, j_farg5, j_farg6, j_farg7
 343   };
 344 
 345   uint int_args = 0;
 346   uint fp_args = 0;
 347 
 348   for (int i = 0; i < total_args_passed; i++) {
 349     switch (sig_bt[i]) {
 350     case T_BOOLEAN:
 351     case T_CHAR:
 352     case T_BYTE:
 353     case T_SHORT:
 354     case T_INT:
 355       if (int_args < SharedRuntime::java_return_convention_max_int) {
 356         regs[i].set1(INT_ArgReg[int_args]->as_VMReg());
 357         int_args ++;
 358       } else {
 359         // Should we have gurantee here?
 360         return -1;
 361       }
 362       break;
 363     case T_VOID:
 364       // halves of T_LONG or T_DOUBLE
 365       assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
 366       regs[i].set_bad();
 367       break;
 368     case T_LONG:
 369       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 370       // fall through
 371     case T_OBJECT:
 372     case T_ARRAY:
 373     case T_ADDRESS:
 374       // Should T_METADATA be added to java_calling_convention as well ?
 375     case T_METADATA:
 376     case T_VALUETYPE:
 377       if (int_args < SharedRuntime::java_return_convention_max_int) {
 378         regs[i].set2(INT_ArgReg[int_args]->as_VMReg());
 379         int_args ++;
 380       } else {
 381         return -1;
 382       }
 383       break;
 384     case T_FLOAT:
 385       if (fp_args < SharedRuntime::java_return_convention_max_float) {
 386         regs[i].set1(FP_ArgReg[fp_args]->as_VMReg());
 387         fp_args ++;
 388       } else {
 389         return -1;
 390       }
 391       break;
 392     case T_DOUBLE:
 393       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 394       if (fp_args < Argument::n_float_register_parameters_j) {
 395         regs[i].set2(FP_ArgReg[fp_args]->as_VMReg());
 396         fp_args ++;
 397       } else {
 398         return -1;
 399       }
 400       break;
 401     default:
 402       ShouldNotReachHere();
 403       break;
 404     }
 405   }


 426 #endif
 427 
 428   __ mov(c_rarg0, rmethod);
 429   __ mov(c_rarg1, lr);
 430   __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)));
 431   __ blrt(rscratch1, 2, 0, 0);
 432   __ maybe_isb();
 433 
 434   __ pop_CPU_state();
 435   // restore sp
 436   __ leave();
 437   __ bind(L);
 438 }
 439 
 440 // For each value type argument, sig includes the list of fields of
 441 // the value type. This utility function computes the number of
 442 // arguments for the call if value types are passed by reference (the
 443 // calling convention the interpreter expects).
 444 static int compute_total_args_passed_int(const GrowableArray<SigEntry>* sig_extended) {
 445   int total_args_passed = 0;
 446   if (ValueTypePassFieldsAsArgs) {
 447      for (int i = 0; i < sig_extended->length(); i++) {
 448        BasicType bt = sig_extended->at(i)._bt;
 449        if (SigEntry::is_reserved_entry(sig_extended, i)) {
 450          // Ignore reserved entry
 451        } else if (bt == T_VALUETYPE) {
 452          // In sig_extended, a value type argument starts with:
 453          // T_VALUETYPE, followed by the types of the fields of the
 454          // value type and T_VOID to mark the end of the value
 455          // type. Value types are flattened so, for instance, in the
 456          // case of a value type with an int field and a value type
 457          // field that itself has 2 fields, an int and a long:
 458          // T_VALUETYPE T_INT T_VALUETYPE T_INT T_LONG T_VOID (second
 459          // slot for the T_LONG) T_VOID (inner T_VALUETYPE) T_VOID
 460          // (outer T_VALUETYPE)
 461          total_args_passed++;
 462          int vt = 1;
 463          do {
 464            i++;
 465            BasicType bt = sig_extended->at(i)._bt;
 466            BasicType prev_bt = sig_extended->at(i-1)._bt;
 467            if (bt == T_VALUETYPE) {
 468              vt++;
 469            } else if (bt == T_VOID &&
 470                       prev_bt != T_LONG &&
 471                       prev_bt != T_DOUBLE) {
 472              vt--;
 473            }
 474          } while (vt != 0);
 475        } else {
 476          total_args_passed++;
 477        }
 478      }
 479   } else {
 480     total_args_passed = sig_extended->length();
 481   }
 482 
 483   return total_args_passed;
 484 }
 485 
 486 
 487 static void gen_c2i_adapter_helper(MacroAssembler* masm, BasicType bt, const VMRegPair& reg_pair, int extraspace, const Address& to) {
 488 
 489     assert(bt != T_VALUETYPE || !ValueTypePassFieldsAsArgs, "no value type here");
 490 
 491     // Say 4 args:
 492     // i   st_off
 493     // 0   32 T_LONG
 494     // 1   24 T_VOID
 495     // 2   16 T_OBJECT
 496     // 3    8 T_BOOL
 497     // -    0 return address
 498     //
 499     // However to make thing extra confusing. Because we can fit a long/double in
 500     // a single slot on a 64 bt vm and it would be silly to break them up, the interpreter
 501     // leaves one slot empty and only stores to a single slot. In this case the
 502     // slot that is occupied is the T_VOID slot. See I said it was confusing.
 503 
 504     // int next_off = st_off - Interpreter::stackElementSize;
 505 
 506     VMReg r_1 = reg_pair.first();
 507     VMReg r_2 = reg_pair.second();
 508 
 509     if (!r_1->is_valid()) {
 510       assert(!r_2->is_valid(), "");
 511       return;
 512     }
 513 
 514     if (r_1->is_stack()) {
 515       // memory to memory use rscratch1
 516       // words_pushed is always 0 so we don't use it.
 517       int ld_off = (r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace /* + word_pushed * wordSize */);

 518       if (!r_2->is_valid()) {
 519         // sign extend??
 520         __ ldrw(rscratch1, Address(sp, ld_off));
 521         __ str(rscratch1, to);
 522 
 523       } else {
 524         __ ldr(rscratch1, Address(sp, ld_off));
 525         __ str(rscratch1, to);
 526       }
 527     } else if (r_1->is_Register()) {
 528       Register r = r_1->as_Register(); 
 529       __ str(r, to);
 530     } else {
 531       assert(r_1->is_FloatRegister(), "");
 532       if (!r_2->is_valid()) {
 533         // only a float use just part of the slot
 534         __ strs(r_1->as_FloatRegister(), to);
 535       } else {
 536         __ strd(r_1->as_FloatRegister(), to);
 537       }


 541 static void gen_c2i_adapter(MacroAssembler *masm,
 542                             const GrowableArray<SigEntry>* sig_extended,
 543                             const VMRegPair *regs,
 544                             Label& skip_fixup,
 545                             address start,
 546                             OopMapSet* oop_maps,
 547                             int& frame_complete,
 548                             int& frame_size_in_words,
 549                             bool alloc_value_receiver) {
 550 
 551   // Before we get into the guts of the C2I adapter, see if we should be here
 552   // at all.  We've come from compiled code and are attempting to jump to the
 553   // interpreter, which means the caller made a static call to get here
 554   // (vcalls always get a compiled target if there is one).  Check for a
 555   // compiled target.  If there is one, we need to patch the caller's call.
 556   patch_callers_callsite(masm);
 557 
 558   __ bind(skip_fixup);
 559 
 560   bool has_value_argument = false;
 561 
 562   if (ValueTypePassFieldsAsArgs) {
 563       // Is there a value type argument?
 564      for (int i = 0; i < sig_extended->length() && !has_value_argument; i++) {
 565        has_value_argument = (sig_extended->at(i)._bt == T_VALUETYPE);
 566      }
 567      if (has_value_argument) {
 568       // There is at least a value type argument: we're coming from
 569       // compiled code so we have no buffers to back the value
 570       // types. Allocate the buffers here with a runtime call.
 571       OopMap* map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
 572  
 573       frame_complete = __ offset();
 574       address the_pc = __ pc();
 575  
 576       __ set_last_Java_frame(noreg, noreg, the_pc, rscratch1);
 577 
 578       __ mov(c_rarg0, rthread);
 579       __ mov(c_rarg1, r1);
 580       __ mov(c_rarg2, (int64_t)alloc_value_receiver);
 581 
 582       __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::allocate_value_types)));
 583       __ blrt(rscratch1, 3, 0, 1);
 584 
 585       oop_maps->add_gc_map((int)(__ pc() - start), map);
 586       __ reset_last_Java_frame(false);
 587 
 588       RegisterSaver::restore_live_registers(masm);
 589 
 590       Label no_exception;
 591       __ ldr(r0, Address(rthread, Thread::pending_exception_offset()));
 592       __ cbz(r0, no_exception);
 593 
 594       __ str(zr, Address(rthread, JavaThread::vm_result_offset()));
 595       __ ldr(r0, Address(rthread, Thread::pending_exception_offset()));
 596       __ b(RuntimeAddress(StubRoutines::forward_exception_entry()));
 597 
 598       __ bind(no_exception);
 599 
 600       // We get an array of objects from the runtime call
 601       __ get_vm_result(r10, rthread); 
 602       __ get_vm_result_2(r1, rthread); // TODO: required to keep the callee Method live?
 603     }
 604   }
 605 
 606   int words_pushed = 0;
 607 
 608   // Since all args are passed on the stack, total_args_passed *
 609   // Interpreter::stackElementSize is the space we need.
 610 
 611   int total_args_passed = compute_total_args_passed_int(sig_extended);
 612   int extraspace = (total_args_passed * Interpreter::stackElementSize) + wordSize;
 613 
 614   // stack is aligned, keep it that way
 615   extraspace = align_up(extraspace, 2 * wordSize);
 616 
 617   __ mov(r13, sp);
 618 
 619   if (extraspace)
 620     __ sub(sp, sp, extraspace);
 621 
 622   // Now write the args into the outgoing interpreter space
 623 
 624   int ignored = 0, next_vt_arg = 0, next_arg_int = 0;
 625   bool has_oop_field = false;
 626 
 627   for (int next_arg_comp = 0; next_arg_comp < total_args_passed; next_arg_comp++) {
 628     BasicType bt = sig_extended->at(next_arg_comp)._bt;
 629     // offset to start parameters
 630     int st_off   = (total_args_passed - next_arg_int - 1) * Interpreter::stackElementSize;
 631 
 632     if (!ValueTypePassFieldsAsArgs || bt != T_VALUETYPE) {
 633 
 634             if (SigEntry::is_reserved_entry(sig_extended, next_arg_comp)) {
 635                continue; // Ignore reserved entry
 636             }
 637 
 638             if (bt == T_VOID) { 
 639                assert(next_arg_comp > 0 && (sig_extended->at(next_arg_comp - 1)._bt == T_LONG || sig_extended->at(next_arg_comp - 1)._bt == T_DOUBLE), "missing half");
 640                next_arg_int ++;
 641                continue;
 642              }
 643 
 644              int next_off = st_off - Interpreter::stackElementSize;
 645              int offset = (bt == T_LONG || bt == T_DOUBLE) ? next_off : st_off;
 646 
 647              gen_c2i_adapter_helper(masm, bt, regs[next_arg_comp], extraspace, Address(sp, offset)); 
 648              next_arg_int ++;
 649    } else {
 650        ignored++;
 651       // get the buffer from the just allocated pool of buffers
 652       int index = arrayOopDesc::base_offset_in_bytes(T_OBJECT) + next_vt_arg * type2aelembytes(T_VALUETYPE);
 653       __ load_heap_oop(rscratch1, Address(r10, index));
 654       next_vt_arg++;
 655       next_arg_int++;
 656       int vt = 1;
 657       // write fields we get from compiled code in registers/stack
 658       // slots to the buffer: we know we are done with that value type
 659       // argument when we hit the T_VOID that acts as an end of value
 660       // type delimiter for this value type. Value types are flattened
 661       // so we might encounter embedded value types. Each entry in
 662       // sig_extended contains a field offset in the buffer.
 663       do {
 664         next_arg_comp++;
 665         BasicType bt = sig_extended->at(next_arg_comp)._bt;
 666         BasicType prev_bt = sig_extended->at(next_arg_comp - 1)._bt;
 667         if (bt == T_VALUETYPE) {
 668           vt++;
 669           ignored++;
 670         } else if (bt == T_VOID && prev_bt != T_LONG && prev_bt != T_DOUBLE) {
 671           vt--;
 672           ignored++;
 673         } else if (SigEntry::is_reserved_entry(sig_extended, next_arg_comp)) {
 674           // Ignore reserved entry
 675         } else {
 676           int off = sig_extended->at(next_arg_comp)._offset;
 677           assert(off > 0, "offset in object should be positive");
 678 
 679           bool is_oop = (bt == T_OBJECT || bt == T_ARRAY);
 680           has_oop_field = has_oop_field || is_oop;
 681 
 682           gen_c2i_adapter_helper(masm, bt, regs[next_arg_comp - ignored], extraspace, Address(r11, off)); 
 683         }
 684       } while (vt != 0);
 685       // pass the buffer to the interpreter
 686       __ str(rscratch1, Address(sp, st_off));
 687    }
 688     
 689   }
 690 
 691 // If a value type was allocated and initialized, apply post barrier to all oop fields
 692   if (has_value_argument && has_oop_field) {
 693     __ push(r13); // save senderSP
 694     __ push(r1); // save callee
 695     // Allocate argument register save area
 696     if (frame::arg_reg_save_area_bytes != 0) {
 697       __ sub(sp, sp, frame::arg_reg_save_area_bytes);
 698     }
 699     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::apply_post_barriers), rthread, r10);
 700     // De-allocate argument register save area
 701     if (frame::arg_reg_save_area_bytes != 0) {
 702       __ add(sp, sp, frame::arg_reg_save_area_bytes);
 703     }
 704     __ pop(r1); // restore callee
 705     __ pop(r13); // restore sender SP
 706   }
 707 
 708   __ mov(esp, sp); // Interp expects args on caller's expression stack


< prev index next >