< prev index next >

src/hotspot/cpu/x86/c1_Runtime1_x86.cpp

Print this page

 832       break;
 833 
 834     case C1StubId::new_instance_id:
 835     case C1StubId::fast_new_instance_id:
 836     case C1StubId::fast_new_instance_init_check_id:
 837       {
 838         Register klass = rdx; // Incoming
 839         Register obj   = rax; // Result
 840 
 841         if (id == C1StubId::new_instance_id) {
 842           __ set_info("new_instance", dont_gc_arguments);
 843         } else if (id == C1StubId::fast_new_instance_id) {
 844           __ set_info("fast new_instance", dont_gc_arguments);
 845         } else {
 846           assert(id == C1StubId::fast_new_instance_init_check_id, "bad C1StubId");
 847           __ set_info("fast new_instance init check", dont_gc_arguments);
 848         }
 849 
 850         __ enter();
 851         OopMap* map = save_live_registers(sasm, 2);
 852         int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);

 853         oop_maps = new OopMapSet();
 854         oop_maps->add_gc_map(call_offset, map);
 855         restore_live_registers_except_rax(sasm);
 856         __ verify_oop(obj);
 857         __ leave();
 858         __ ret(0);
 859 
 860         // rax,: new instance
 861       }
 862 
 863       break;
 864 
 865     case C1StubId::counter_overflow_id:
 866       {
 867         Register bci = rax, method = rbx;
 868         __ enter();
 869         OopMap* map = save_live_registers(sasm, 3);
 870         // Retrieve bci
 871         __ movl(bci, Address(rbp, 2*BytesPerWord));
 872         // And a pointer to the Method*
 873         __ movptr(method, Address(rbp, 3*BytesPerWord));
 874         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
 875         oop_maps = new OopMapSet();
 876         oop_maps->add_gc_map(call_offset, map);
 877         restore_live_registers(sasm);
 878         __ leave();
 879         __ ret(0);
 880       }
 881       break;
 882 
 883     case C1StubId::new_type_array_id:
 884     case C1StubId::new_object_array_id:

 885       {
 886         Register length   = rbx; // Incoming
 887         Register klass    = rdx; // Incoming
 888         Register obj      = rax; // Result
 889 
 890         if (id == C1StubId::new_type_array_id) {
 891           __ set_info("new_type_array", dont_gc_arguments);
 892         } else {
 893           __ set_info("new_object_array", dont_gc_arguments);


 894         }
 895 
 896 #ifdef ASSERT
 897         // assert object type is really an array of the proper kind
 898         {
 899           Label ok;
 900           Register t0 = obj;
 901           __ movl(t0, Address(klass, Klass::layout_helper_offset()));
 902           __ sarl(t0, Klass::_lh_array_tag_shift);
 903           int tag = ((id == C1StubId::new_type_array_id)
 904                      ? Klass::_lh_array_tag_type_value
 905                      : Klass::_lh_array_tag_obj_value);
 906           __ cmpl(t0, tag);
 907           __ jcc(Assembler::equal, ok);
 908           __ stop("assert(is an array klass)");
















 909           __ should_not_reach_here();
 910           __ bind(ok);
 911         }
 912 #endif // ASSERT
 913 
 914         __ enter();
 915         OopMap* map = save_live_registers(sasm, 3);
 916         int call_offset;
 917         if (id == C1StubId::new_type_array_id) {
 918           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
 919         } else {
 920           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);



 921         }
 922 
 923         oop_maps = new OopMapSet();
 924         oop_maps->add_gc_map(call_offset, map);
 925         restore_live_registers_except_rax(sasm);
 926 
 927         __ verify_oop(obj);
 928         __ leave();
 929         __ ret(0);
 930 
 931         // rax,: new array
 932       }
 933       break;
 934 
 935     case C1StubId::new_multi_array_id:
 936       { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
 937         // rax,: klass
 938         // rbx,: rank
 939         // rcx: address of 1st dimension
 940         OopMap* map = save_live_registers(sasm, 4);
 941         int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
 942 
 943         oop_maps = new OopMapSet();
 944         oop_maps->add_gc_map(call_offset, map);
 945         restore_live_registers_except_rax(sasm);
 946 
 947         // rax,: new multi array
 948         __ verify_oop(rax);
 949       }
 950       break;
 951 













































































 952     case C1StubId::register_finalizer_id:
 953       {
 954         __ set_info("register_finalizer", dont_gc_arguments);
 955 
 956         // This is called via call_runtime so the arguments
 957         // will be place in C abi locations
 958 
 959         __ verify_oop(c_rarg0);
 960         __ mov(rax, c_rarg0);
 961 
 962         // load the klass and check the has finalizer flag
 963         Label register_finalizer;
 964         Register t = rsi;
 965         __ load_klass(t, rax, rscratch1);
 966         __ testb(Address(t, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer);
 967         __ jcc(Assembler::notZero, register_finalizer);
 968         __ ret(0);
 969 
 970         __ bind(register_finalizer);
 971         __ enter();

1025         //       activation and we are calling a leaf VM function only.
1026         generate_unwind_exception(sasm);
1027       }
1028       break;
1029 
1030     case C1StubId::throw_array_store_exception_id:
1031       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1032         // tos + 0: link
1033         //     + 1: return address
1034         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1035       }
1036       break;
1037 
1038     case C1StubId::throw_class_cast_exception_id:
1039       { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1040         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1041       }
1042       break;
1043 
1044     case C1StubId::throw_incompatible_class_change_error_id:
1045       { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments);
1046         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1047       }
1048       break;












1049 
1050     case C1StubId::slow_subtype_check_id:
1051       {
1052         // Typical calling sequence:
1053         // __ push(klass_RInfo);  // object klass or other subclass
1054         // __ push(sup_k_RInfo);  // array element klass or other superclass
1055         // __ call(slow_subtype_check);
1056         // Note that the subclass is pushed first, and is therefore deepest.
1057         // Previous versions of this code reversed the names 'sub' and 'super'.
1058         // This was operationally harmless but made the code unreadable.
1059         enum layout {
1060           rax_off, SLOT2(raxH_off)
1061           rcx_off, SLOT2(rcxH_off)
1062           rsi_off, SLOT2(rsiH_off)
1063           rdi_off, SLOT2(rdiH_off)
1064           // saved_rbp_off, SLOT2(saved_rbpH_off)
1065           return_off, SLOT2(returnH_off)
1066           sup_k_off, SLOT2(sup_kH_off)
1067           klass_off, SLOT2(superH_off)
1068           framesize,

 832       break;
 833 
 834     case C1StubId::new_instance_id:
 835     case C1StubId::fast_new_instance_id:
 836     case C1StubId::fast_new_instance_init_check_id:
 837       {
 838         Register klass = rdx; // Incoming
 839         Register obj   = rax; // Result
 840 
 841         if (id == C1StubId::new_instance_id) {
 842           __ set_info("new_instance", dont_gc_arguments);
 843         } else if (id == C1StubId::fast_new_instance_id) {
 844           __ set_info("fast new_instance", dont_gc_arguments);
 845         } else {
 846           assert(id == C1StubId::fast_new_instance_init_check_id, "bad C1StubId");
 847           __ set_info("fast new_instance init check", dont_gc_arguments);
 848         }
 849 
 850         __ enter();
 851         OopMap* map = save_live_registers(sasm, 2);
 852         int call_offset;
 853         call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
 854         oop_maps = new OopMapSet();
 855         oop_maps->add_gc_map(call_offset, map);
 856         restore_live_registers_except_rax(sasm);
 857         __ verify_oop(obj);
 858         __ leave();
 859         __ ret(0);
 860 
 861         // rax,: new instance
 862       }
 863 
 864       break;
 865 
 866     case C1StubId::counter_overflow_id:
 867       {
 868         Register bci = rax, method = rbx;
 869         __ enter();
 870         OopMap* map = save_live_registers(sasm, 3);
 871         // Retrieve bci
 872         __ movl(bci, Address(rbp, 2*BytesPerWord));
 873         // And a pointer to the Method*
 874         __ movptr(method, Address(rbp, 3*BytesPerWord));
 875         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
 876         oop_maps = new OopMapSet();
 877         oop_maps->add_gc_map(call_offset, map);
 878         restore_live_registers(sasm);
 879         __ leave();
 880         __ ret(0);
 881       }
 882       break;
 883 
 884     case C1StubId::new_type_array_id:
 885     case C1StubId::new_object_array_id:
 886     case C1StubId::new_null_free_array_id:
 887       {
 888         Register length   = rbx; // Incoming
 889         Register klass    = rdx; // Incoming
 890         Register obj      = rax; // Result
 891 
 892         if (id == C1StubId::new_type_array_id) {
 893           __ set_info("new_type_array", dont_gc_arguments);
 894         } else if (id == C1StubId::new_object_array_id) {
 895           __ set_info("new_object_array", dont_gc_arguments);
 896         } else {
 897           __ set_info("new_null_free_array", dont_gc_arguments);
 898         }
 899 
 900 #ifdef ASSERT
 901         // assert object type is really an array of the proper kind
 902         {
 903           Label ok;
 904           Register t0 = obj;
 905           __ movl(t0, Address(klass, Klass::layout_helper_offset()));
 906           __ sarl(t0, Klass::_lh_array_tag_shift);
 907           switch (id) {
 908           case C1StubId::new_type_array_id:
 909             __ cmpl(t0, Klass::_lh_array_tag_type_value);
 910             __ jcc(Assembler::equal, ok);
 911             __ stop("assert(is a type array klass)");
 912             break;
 913           case C1StubId::new_object_array_id:
 914             __ cmpl(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
 915             __ jcc(Assembler::equal, ok);
 916             __ cmpl(t0, Klass::_lh_array_tag_vt_value);  // new "[LVT;"
 917             __ jcc(Assembler::equal, ok);
 918             __ stop("assert(is an object or inline type array klass)");
 919             break;
 920           case C1StubId::new_null_free_array_id:
 921             __ cmpl(t0, Klass::_lh_array_tag_vt_value);  // the array can be a flat array.
 922             __ jcc(Assembler::equal, ok);
 923             __ cmpl(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
 924             __ jcc(Assembler::equal, ok);
 925             __ stop("assert(is an object or inline type array klass)");
 926             break;
 927           default:  ShouldNotReachHere();
 928           }
 929           __ should_not_reach_here();
 930           __ bind(ok);
 931         }
 932 #endif // ASSERT
 933 
 934         __ enter();
 935         OopMap* map = save_live_registers(sasm, 3);
 936         int call_offset;
 937         if (id == C1StubId::new_type_array_id) {
 938           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
 939         } else if (id == C1StubId::new_object_array_id) {
 940           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
 941         } else {
 942           assert(id == C1StubId::new_null_free_array_id, "must be");
 943           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
 944         }
 945 
 946         oop_maps = new OopMapSet();
 947         oop_maps->add_gc_map(call_offset, map);
 948         restore_live_registers_except_rax(sasm);
 949 
 950         __ verify_oop(obj);
 951         __ leave();
 952         __ ret(0);
 953 
 954         // rax,: new array
 955       }
 956       break;
 957 
 958     case C1StubId::new_multi_array_id:
 959       { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
 960         // rax,: klass
 961         // rbx,: rank
 962         // rcx: address of 1st dimension
 963         OopMap* map = save_live_registers(sasm, 4);
 964         int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
 965 
 966         oop_maps = new OopMapSet();
 967         oop_maps->add_gc_map(call_offset, map);
 968         restore_live_registers_except_rax(sasm);
 969 
 970         // rax,: new multi array
 971         __ verify_oop(rax);
 972       }
 973       break;
 974 
 975     case C1StubId::load_flat_array_id:
 976       {
 977         StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
 978         OopMap* map = save_live_registers(sasm, 3);
 979 
 980         // Called with store_parameter and not C abi
 981 
 982         f.load_argument(1, rax); // rax,: array
 983         f.load_argument(0, rbx); // rbx,: index
 984         int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, load_flat_array), rax, rbx);
 985 
 986         oop_maps = new OopMapSet();
 987         oop_maps->add_gc_map(call_offset, map);
 988         restore_live_registers_except_rax(sasm);
 989 
 990         // rax,: loaded element at array[index]
 991         __ verify_oop(rax);
 992       }
 993       break;
 994 
 995     case C1StubId::store_flat_array_id:
 996       {
 997         StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
 998         OopMap* map = save_live_registers(sasm, 4);
 999 
1000         // Called with store_parameter and not C abi
1001 
1002         f.load_argument(2, rax); // rax,: array
1003         f.load_argument(1, rbx); // rbx,: index
1004         f.load_argument(0, rcx); // rcx,: value
1005         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), rax, rbx, rcx);
1006 
1007         oop_maps = new OopMapSet();
1008         oop_maps->add_gc_map(call_offset, map);
1009         restore_live_registers_except_rax(sasm);
1010       }
1011       break;
1012 
1013     case C1StubId::substitutability_check_id:
1014       {
1015         StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
1016         OopMap* map = save_live_registers(sasm, 3);
1017 
1018         // Called with store_parameter and not C abi
1019 
1020         f.load_argument(1, rax); // rax,: left
1021         f.load_argument(0, rbx); // rbx,: right
1022         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), rax, rbx);
1023 
1024         oop_maps = new OopMapSet();
1025         oop_maps->add_gc_map(call_offset, map);
1026         restore_live_registers_except_rax(sasm);
1027 
1028         // rax,: are the two operands substitutable
1029       }
1030       break;
1031 
1032 
1033     case C1StubId::buffer_inline_args_id:
1034     case C1StubId::buffer_inline_args_no_receiver_id:
1035       {
1036         const char* name = (id == C1StubId::buffer_inline_args_id) ?
1037           "buffer_inline_args" : "buffer_inline_args_no_receiver";
1038         StubFrame f(sasm, name, dont_gc_arguments);
1039         OopMap* map = save_live_registers(sasm, 2);
1040         Register method = rbx;
1041         address entry = (id == C1StubId::buffer_inline_args_id) ?
1042           CAST_FROM_FN_PTR(address, buffer_inline_args) :
1043           CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
1044         int call_offset = __ call_RT(rax, noreg, entry, method);
1045         oop_maps = new OopMapSet();
1046         oop_maps->add_gc_map(call_offset, map);
1047         restore_live_registers_except_rax(sasm);
1048         __ verify_oop(rax);  // rax: an array of buffered value objects
1049       }
1050       break;
1051 
1052     case C1StubId::register_finalizer_id:
1053       {
1054         __ set_info("register_finalizer", dont_gc_arguments);
1055 
1056         // This is called via call_runtime so the arguments
1057         // will be place in C abi locations
1058 
1059         __ verify_oop(c_rarg0);
1060         __ mov(rax, c_rarg0);
1061 
1062         // load the klass and check the has finalizer flag
1063         Label register_finalizer;
1064         Register t = rsi;
1065         __ load_klass(t, rax, rscratch1);
1066         __ testb(Address(t, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer);
1067         __ jcc(Assembler::notZero, register_finalizer);
1068         __ ret(0);
1069 
1070         __ bind(register_finalizer);
1071         __ enter();

1125         //       activation and we are calling a leaf VM function only.
1126         generate_unwind_exception(sasm);
1127       }
1128       break;
1129 
1130     case C1StubId::throw_array_store_exception_id:
1131       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1132         // tos + 0: link
1133         //     + 1: return address
1134         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1135       }
1136       break;
1137 
1138     case C1StubId::throw_class_cast_exception_id:
1139       { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1140         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1141       }
1142       break;
1143 
1144     case C1StubId::throw_incompatible_class_change_error_id:
1145       { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments);
1146         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1147       }
1148       break;
1149 
1150     case C1StubId::throw_illegal_monitor_state_exception_id:
1151       { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
1152         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
1153       }
1154       break;
1155 
1156     case C1StubId::throw_identity_exception_id:
1157       { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
1158         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
1159       }
1160       break;
1161 
1162     case C1StubId::slow_subtype_check_id:
1163       {
1164         // Typical calling sequence:
1165         // __ push(klass_RInfo);  // object klass or other subclass
1166         // __ push(sup_k_RInfo);  // array element klass or other superclass
1167         // __ call(slow_subtype_check);
1168         // Note that the subclass is pushed first, and is therefore deepest.
1169         // Previous versions of this code reversed the names 'sub' and 'super'.
1170         // This was operationally harmless but made the code unreadable.
1171         enum layout {
1172           rax_off, SLOT2(raxH_off)
1173           rcx_off, SLOT2(rcxH_off)
1174           rsi_off, SLOT2(rsiH_off)
1175           rdi_off, SLOT2(rdiH_off)
1176           // saved_rbp_off, SLOT2(saved_rbpH_off)
1177           return_off, SLOT2(returnH_off)
1178           sup_k_off, SLOT2(sup_kH_off)
1179           klass_off, SLOT2(superH_off)
1180           framesize,
< prev index next >