< prev index next >

src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp

Print this page

 691       break;
 692 
 693     case StubId::c1_new_instance_id:
 694     case StubId::c1_fast_new_instance_id:
 695     case StubId::c1_fast_new_instance_init_check_id:
 696       {
 697         Register klass = r3; // Incoming
 698         Register obj   = r0; // Result
 699 
 700         if (id == StubId::c1_new_instance_id) {
 701           __ set_info("new_instance", dont_gc_arguments);
 702         } else if (id == StubId::c1_fast_new_instance_id) {
 703           __ set_info("fast new_instance", dont_gc_arguments);
 704         } else {
 705           assert(id == StubId::c1_fast_new_instance_init_check_id, "bad StubId");
 706           __ set_info("fast new_instance init check", dont_gc_arguments);
 707         }
 708 
 709         __ enter();
 710         OopMap* map = save_live_registers(sasm);
 711         int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);

 712         oop_maps = new OopMapSet();
 713         oop_maps->add_gc_map(call_offset, map);
 714         restore_live_registers_except_r0(sasm);
 715         __ verify_oop(obj);
 716         __ leave();
 717         __ ret(lr);
 718 
 719         // r0,: new instance
 720       }
 721 
 722       break;
 723 
 724     case StubId::c1_counter_overflow_id:
 725       {
 726         Register bci = r0, method = r1;
 727         __ enter();
 728         OopMap* map = save_live_registers(sasm);
 729         // Retrieve bci
 730         __ ldrw(bci, Address(rfp, 2*BytesPerWord));
 731         // And a pointer to the Method*
 732         __ ldr(method, Address(rfp, 3*BytesPerWord));
 733         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
 734         oop_maps = new OopMapSet();
 735         oop_maps->add_gc_map(call_offset, map);
 736         restore_live_registers(sasm);
 737         __ leave();
 738         __ ret(lr);
 739       }
 740       break;
 741 
 742     case StubId::c1_new_type_array_id:
 743     case StubId::c1_new_object_array_id:

 744       {
 745         Register length   = r19; // Incoming
 746         Register klass    = r3; // Incoming
 747         Register obj      = r0; // Result
 748 
 749         if (id == StubId::c1_new_type_array_id) {
 750           __ set_info("new_type_array", dont_gc_arguments);
 751         } else {
 752           __ set_info("new_object_array", dont_gc_arguments);


 753         }
 754 
 755 #ifdef ASSERT
 756         // assert object type is really an array of the proper kind
 757         {
 758           Label ok;
 759           Register t0 = obj;
 760           __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
 761           __ asrw(t0, t0, Klass::_lh_array_tag_shift);
 762           int tag = ((id == StubId::c1_new_type_array_id)
 763                      ? Klass::_lh_array_tag_type_value
 764                      : Klass::_lh_array_tag_obj_value);
 765           __ mov(rscratch1, tag);
 766           __ cmpw(t0, rscratch1);
 767           __ br(Assembler::EQ, ok);
 768           __ stop("assert(is an array klass)");















 769           __ should_not_reach_here();
 770           __ bind(ok);
 771         }
 772 #endif // ASSERT
 773 
 774         __ enter();
 775         OopMap* map = save_live_registers(sasm);
 776         int call_offset;
 777         if (id == StubId::c1_new_type_array_id) {
 778           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
 779         } else {
 780           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);



 781         }
 782 
 783         oop_maps = new OopMapSet();
 784         oop_maps->add_gc_map(call_offset, map);
 785         restore_live_registers_except_r0(sasm);
 786 
 787         __ verify_oop(obj);
 788         __ leave();
 789         __ ret(lr);
 790 
 791         // r0: new array
 792       }
 793       break;
 794 
 795     case StubId::c1_new_multi_array_id:
 796       { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
 797         // r0,: klass
 798         // r19,: rank
 799         // r2: address of 1st dimension
 800         OopMap* map = save_live_registers(sasm);
 801         __ mov(c_rarg1, r0);
 802         __ mov(c_rarg3, r2);
 803         __ mov(c_rarg2, r19);
 804         int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
 805 
 806         oop_maps = new OopMapSet();
 807         oop_maps->add_gc_map(call_offset, map);
 808         restore_live_registers_except_r0(sasm);
 809 
 810         // r0,: new multi array
 811         __ verify_oop(r0);
 812       }
 813       break;
 814 























































































 815     case StubId::c1_register_finalizer_id:
 816       {
 817         __ set_info("register_finalizer", dont_gc_arguments);
 818 
 819         // This is called via call_runtime so the arguments
 820         // will be place in C abi locations
 821 
 822         __ verify_oop(c_rarg0);
 823 
 824         // load the klass and check the has finalizer flag
 825         Label register_finalizer;
 826         Register t = r5;
 827         __ load_klass(t, r0);
 828         __ ldrb(t, Address(t, Klass::misc_flags_offset()));
 829         __ tbnz(t, exact_log2(KlassFlags::_misc_has_finalizer), register_finalizer);
 830         __ ret(lr);
 831 
 832         __ bind(register_finalizer);
 833         __ enter();
 834         OopMap* oop_map = save_live_registers(sasm);
 835         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
 836         oop_maps = new OopMapSet();
 837         oop_maps->add_gc_map(call_offset, oop_map);
 838 
 839         // Now restore all the live registers
 840         restore_live_registers(sasm);
 841 
 842         __ leave();
 843         __ ret(lr);
 844       }
 845       break;
 846 
 847     case StubId::c1_throw_class_cast_exception_id:
 848       { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return);
 849         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
 850       }
 851       break;
 852 
 853     case StubId::c1_throw_incompatible_class_change_error_id:
 854       { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments, does_not_return);
 855         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
 856       }
 857       break;
 858 












 859     case StubId::c1_slow_subtype_check_id:
 860       {
 861         // Typical calling sequence:
 862         // __ push(klass_RInfo);  // object klass or other subclass
 863         // __ push(sup_k_RInfo);  // array element klass or other superclass
 864         // __ bl(slow_subtype_check);
 865         // Note that the subclass is pushed first, and is therefore deepest.
 866         enum layout {
 867           r0_off, r0_off_hi,
 868           r2_off, r2_off_hi,
 869           r4_off, r4_off_hi,
 870           r5_off, r5_off_hi,
 871           sup_k_off, sup_k_off_hi,
 872           klass_off, klass_off_hi,
 873           framesize,
 874           result_off = sup_k_off
 875         };
 876 
 877         __ set_info("slow_subtype_check", dont_gc_arguments);
 878         __ push(RegSet::of(r0, r2, r4, r5), sp);

1097         __ leave();
1098         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1099         assert(deopt_blob != nullptr, "deoptimization blob must have been created");
1100 
1101         __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1102       }
1103       break;
1104 
1105     case StubId::c1_dtrace_object_alloc_id:
1106       { // c_rarg0: object
1107         StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1108         save_live_registers(sasm);
1109 
1110         __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), c_rarg0);
1111 
1112         restore_live_registers(sasm);
1113       }
1114       break;
1115 
1116     default:


1117       { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
1118         __ mov(r0, (int)id);
1119         __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1120       }
1121       break;
1122     }
1123   }


1124   return oop_maps;
1125 }
1126 
1127 #undef __
1128 
1129 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); }

 691       break;
 692 
 693     case StubId::c1_new_instance_id:
 694     case StubId::c1_fast_new_instance_id:
 695     case StubId::c1_fast_new_instance_init_check_id:
 696       {
 697         Register klass = r3; // Incoming
 698         Register obj   = r0; // Result
 699 
 700         if (id == StubId::c1_new_instance_id) {
 701           __ set_info("new_instance", dont_gc_arguments);
 702         } else if (id == StubId::c1_fast_new_instance_id) {
 703           __ set_info("fast new_instance", dont_gc_arguments);
 704         } else {
 705           assert(id == StubId::c1_fast_new_instance_init_check_id, "bad StubId");
 706           __ set_info("fast new_instance init check", dont_gc_arguments);
 707         }
 708 
 709         __ enter();
 710         OopMap* map = save_live_registers(sasm);
 711         int call_offset;
 712         call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
 713         oop_maps = new OopMapSet();
 714         oop_maps->add_gc_map(call_offset, map);
 715         restore_live_registers_except_r0(sasm);
 716         __ verify_oop(obj);
 717         __ leave();
 718         __ ret(lr);
 719 
 720         // r0,: new instance
 721       }
 722 
 723       break;
 724 
 725     case StubId::c1_counter_overflow_id:
 726       {
 727         Register bci = r0, method = r1;
 728         __ enter();
 729         OopMap* map = save_live_registers(sasm);
 730         // Retrieve bci
 731         __ ldrw(bci, Address(rfp, 2*BytesPerWord));
 732         // And a pointer to the Method*
 733         __ ldr(method, Address(rfp, 3*BytesPerWord));
 734         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
 735         oop_maps = new OopMapSet();
 736         oop_maps->add_gc_map(call_offset, map);
 737         restore_live_registers(sasm);
 738         __ leave();
 739         __ ret(lr);
 740       }
 741       break;
 742 
 743     case StubId::c1_new_type_array_id:
 744     case StubId::c1_new_object_array_id:
 745     case StubId::c1_new_null_free_array_id:
 746       {
 747         Register length   = r19; // Incoming
 748         Register klass    = r3; // Incoming
 749         Register obj      = r0; // Result
 750 
 751         if (id == StubId::c1_new_type_array_id) {
 752           __ set_info("new_type_array", dont_gc_arguments);
 753         } else if (id == StubId::c1_new_object_array_id) {
 754           __ set_info("new_object_array", dont_gc_arguments);
 755         } else {
 756           __ set_info("new_null_free_array", dont_gc_arguments);
 757         }
 758 
 759 #ifdef ASSERT
 760         // assert object type is really an array of the proper kind
 761         {
 762           Label ok;
 763           Register t0 = obj;
 764           __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
 765           __ asrw(t0, t0, Klass::_lh_array_tag_shift);
 766           switch (id) {
 767           case StubId::c1_new_type_array_id:
 768             __ cmpw(t0, Klass::_lh_array_tag_type_value);
 769             __ br(Assembler::EQ, ok);
 770             __ stop("assert(is a type array klass)");
 771             break;
 772           case StubId::c1_new_object_array_id:
 773             __ cmpw(t0, Klass::_lh_array_tag_ref_value); // new "[Ljava/lang/Object;"
 774             __ br(Assembler::EQ, ok);
 775             __ cmpw(t0, Klass::_lh_array_tag_flat_value);  // new "[LVT;"
 776             __ br(Assembler::EQ, ok);
 777             __ stop("assert(is an object or inline type array klass)");
 778             break;
 779           case StubId::c1_new_null_free_array_id:
 780             __ cmpw(t0, Klass::_lh_array_tag_flat_value);  // the array can be a flat array.
 781             __ br(Assembler::EQ, ok);
 782             __ cmpw(t0, Klass::_lh_array_tag_ref_value); // the array cannot be a flat array (due to the InlineArrayElementMaxFlatSize, etc.)
 783             __ br(Assembler::EQ, ok);
 784             __ stop("assert(is an object or inline type array klass)");
 785             break;
 786           default:  ShouldNotReachHere();
 787           }
 788           __ should_not_reach_here();
 789           __ bind(ok);
 790         }
 791 #endif // ASSERT
 792 
 793         __ enter();
 794         OopMap* map = save_live_registers(sasm);
 795         int call_offset;
 796         if (id == StubId::c1_new_type_array_id) {
 797           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
 798         } else if (id == StubId::c1_new_object_array_id) {
 799           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
 800         } else {
 801           assert(id == StubId::c1_new_null_free_array_id, "must be");
 802           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
 803         }
 804 
 805         oop_maps = new OopMapSet();
 806         oop_maps->add_gc_map(call_offset, map);
 807         restore_live_registers_except_r0(sasm);
 808 
 809         __ verify_oop(obj);
 810         __ leave();
 811         __ ret(lr);
 812 
 813         // r0: new array
 814       }
 815       break;
 816 
 817     case StubId::c1_new_multi_array_id:
 818       { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
 819         // r0,: klass
 820         // r19,: rank
 821         // r2: address of 1st dimension
 822         OopMap* map = save_live_registers(sasm);
 823         __ mov(c_rarg1, r0);
 824         __ mov(c_rarg3, r2);
 825         __ mov(c_rarg2, r19);
 826         int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
 827 
 828         oop_maps = new OopMapSet();
 829         oop_maps->add_gc_map(call_offset, map);
 830         restore_live_registers_except_r0(sasm);
 831 
 832         // r0,: new multi array
 833         __ verify_oop(r0);
 834       }
 835       break;
 836 
 837     case StubId::c1_buffer_inline_args_id:
 838     case StubId::c1_buffer_inline_args_no_receiver_id:
 839       {
 840         const char* name = (id == StubId::c1_buffer_inline_args_id) ?
 841           "buffer_inline_args" : "buffer_inline_args_no_receiver";
 842         StubFrame f(sasm, name, dont_gc_arguments);
 843         OopMap* map = save_live_registers(sasm);
 844         Register method = r19;   // Incoming
 845         address entry = (id == StubId::c1_buffer_inline_args_id) ?
 846           CAST_FROM_FN_PTR(address, buffer_inline_args) :
 847           CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
 848         // This is called from a C1 method's scalarized entry point
 849         // where r0-r7 may be holding live argument values so we can't
 850         // return the result in r0 as the other stubs do. LR is used as
 851         // a temporary below to avoid the result being clobbered by
 852         // restore_live_registers. It's saved and restored by
 853         // StubAssembler::prologue and epilogue anyway.
 854         int call_offset = __ call_RT(lr, noreg, entry, method);
 855         oop_maps = new OopMapSet();
 856         oop_maps->add_gc_map(call_offset, map);
 857         restore_live_registers(sasm);
 858         __ mov(r20, lr);
 859         __ verify_oop(r20);  // r20: an array of buffered value objects
 860      }
 861      break;
 862 
 863     case StubId::c1_load_flat_array_id:
 864       {
 865         StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
 866         OopMap* map = save_live_registers(sasm);
 867 
 868         // Called with store_parameter and not C abi
 869 
 870         f.load_argument(1, r0); // r0,: array
 871         f.load_argument(0, r1); // r1,: index
 872         int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, load_flat_array), r0, r1);
 873 
 874         // Ensure the stores that initialize the buffer are visible
 875         // before any subsequent store that publishes this reference.
 876         __ membar(Assembler::StoreStore);
 877 
 878         oop_maps = new OopMapSet();
 879         oop_maps->add_gc_map(call_offset, map);
 880         restore_live_registers_except_r0(sasm);
 881 
 882         // r0: loaded element at array[index]
 883         __ verify_oop(r0);
 884       }
 885       break;
 886 
 887     case StubId::c1_store_flat_array_id:
 888       {
 889         StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
 890         OopMap* map = save_live_registers(sasm);
 891 
 892         // Called with store_parameter and not C abi
 893 
 894         f.load_argument(2, r0); // r0: array
 895         f.load_argument(1, r1); // r1: index
 896         f.load_argument(0, r2); // r2: value
 897         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), r0, r1, r2);
 898 
 899         oop_maps = new OopMapSet();
 900         oop_maps->add_gc_map(call_offset, map);
 901         restore_live_registers_except_r0(sasm);
 902       }
 903       break;
 904 
 905     case StubId::c1_substitutability_check_id:
 906       {
 907         StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
 908         OopMap* map = save_live_registers(sasm);
 909 
 910         // Called with store_parameter and not C abi
 911 
 912         f.load_argument(1, r1); // r1,: left
 913         f.load_argument(0, r2); // r2,: right
 914         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), r1, r2);
 915 
 916         oop_maps = new OopMapSet();
 917         oop_maps->add_gc_map(call_offset, map);
 918         restore_live_registers_except_r0(sasm);
 919 
 920         // r0,: are the two operands substitutable
 921       }
 922       break;
 923 
 924     case StubId::c1_register_finalizer_id:
 925       {
 926         __ set_info("register_finalizer", dont_gc_arguments);
 927 
 928         // This is called via call_runtime so the arguments
 929         // will be place in C abi locations
 930 
 931         __ verify_oop(c_rarg0);
 932 
 933         // load the klass and check the has finalizer flag
 934         Label register_finalizer;
 935         Register t = r5;
 936         __ load_klass(t, r0);
 937         __ ldrb(t, Address(t, Klass::misc_flags_offset()));
 938         __ tbnz(t, exact_log2(KlassFlags::_misc_has_finalizer), register_finalizer);
 939         __ ret(lr);
 940 
 941         __ bind(register_finalizer);
 942         __ enter();
 943         OopMap* oop_map = save_live_registers(sasm);
 944         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
 945         oop_maps = new OopMapSet();
 946         oop_maps->add_gc_map(call_offset, oop_map);
 947 
 948         // Now restore all the live registers
 949         restore_live_registers(sasm);
 950 
 951         __ leave();
 952         __ ret(lr);
 953       }
 954       break;
 955 
 956     case StubId::c1_throw_class_cast_exception_id:
 957       { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return);
 958         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
 959       }
 960       break;
 961 
 962     case StubId::c1_throw_incompatible_class_change_error_id:
 963       { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments, does_not_return);
 964         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
 965       }
 966       break;
 967 
 968     case StubId::c1_throw_illegal_monitor_state_exception_id:
 969       { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
 970         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
 971       }
 972       break;
 973 
 974     case StubId::c1_throw_identity_exception_id:
 975       { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
 976         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
 977       }
 978       break;
 979 
 980     case StubId::c1_slow_subtype_check_id:
 981       {
 982         // Typical calling sequence:
 983         // __ push(klass_RInfo);  // object klass or other subclass
 984         // __ push(sup_k_RInfo);  // array element klass or other superclass
 985         // __ bl(slow_subtype_check);
 986         // Note that the subclass is pushed first, and is therefore deepest.
 987         enum layout {
 988           r0_off, r0_off_hi,
 989           r2_off, r2_off_hi,
 990           r4_off, r4_off_hi,
 991           r5_off, r5_off_hi,
 992           sup_k_off, sup_k_off_hi,
 993           klass_off, klass_off_hi,
 994           framesize,
 995           result_off = sup_k_off
 996         };
 997 
 998         __ set_info("slow_subtype_check", dont_gc_arguments);
 999         __ push(RegSet::of(r0, r2, r4, r5), sp);

1218         __ leave();
1219         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1220         assert(deopt_blob != nullptr, "deoptimization blob must have been created");
1221 
1222         __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1223       }
1224       break;
1225 
1226     case StubId::c1_dtrace_object_alloc_id:
1227       { // c_rarg0: object
1228         StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1229         save_live_registers(sasm);
1230 
1231         __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), c_rarg0);
1232 
1233         restore_live_registers(sasm);
1234       }
1235       break;
1236 
1237     default:
1238       // FIXME: For unhandled trap_id this code fails with assert during vm intialization
1239       // rather than insert a call to unimplemented_entry
1240       { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
1241         __ mov(r0, (int)id);
1242         __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1243       }
1244       break;
1245     }
1246   }
1247 
1248 
1249   return oop_maps;
1250 }
1251 
1252 #undef __
1253 
1254 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); }
< prev index next >