< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.cpp

Print this page




 881   else
 882     Assembler:: notify(type);
 883 }
 884 
 885 // Look up the method for a megamorphic invokeinterface call.
 886 // The target method is determined by <intf_klass, itable_index>.
 887 // The receiver klass is in recv_klass.
 888 // On success, the result will be in method_result, and execution falls through.
 889 // On failure, execution transfers to the given label.
 890 void MacroAssembler::lookup_interface_method(Register recv_klass,
 891                                              Register intf_klass,
 892                                              RegisterOrConstant itable_index,
 893                                              Register method_result,
 894                                              Register scan_temp,
 895                                              Label& L_no_such_interface) {
 896   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
 897   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
 898          "caller must use same register for non-constant itable index as for method");
 899 
 900   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
 901   int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
 902   int itentry_off = itableMethodEntry::method_offset_in_bytes();
 903   int scan_step   = itableOffsetEntry::size() * wordSize;
 904   int vte_size    = vtableEntry::size() * wordSize;
 905   assert(vte_size == wordSize, "else adjust times_vte_scale");
 906 
 907   ldrw(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize));
 908 
 909   // %%% Could store the aligned, prescaled offset in the klassoop.
 910   // lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
 911   lea(scan_temp, Address(recv_klass, scan_temp, Address::lsl(3)));
 912   add(scan_temp, scan_temp, vtable_base);
 913   if (HeapWordsPerLong > 1) {
 914     // Round up to align_object_offset boundary
 915     // see code for instanceKlass::start_of_itable!
 916     round_to(scan_temp, BytesPerLong);
 917   }
 918 
 919   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
 920   assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
 921   // lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
 922   lea(recv_klass, Address(recv_klass, itable_index, Address::lsl(3)));
 923   if (itentry_off)
 924     add(recv_klass, recv_klass, itentry_off);
 925 
 926   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
 927   //   if (scan->interface() == intf) {


 946     bind(search);
 947 
 948     // Check that the previous entry is non-null.  A null entry means that
 949     // the receiver class doesn't implement the interface, and wasn't the
 950     // same as when the caller was compiled.
 951     cbz(method_result, L_no_such_interface);
 952     add(scan_temp, scan_temp, scan_step);
 953   }
 954 
 955   bind(found_method);
 956 
 957   // Got a hit.
 958   ldr(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
 959   ldr(method_result, Address(recv_klass, scan_temp));
 960 }
 961 
 962 // virtual method calling
 963 void MacroAssembler::lookup_virtual_method(Register recv_klass,
 964                                            RegisterOrConstant vtable_index,
 965                                            Register method_result) {
 966   const int base = InstanceKlass::vtable_start_offset() * wordSize;
 967   assert(vtableEntry::size() * wordSize == 8,
 968          "adjust the scaling in the code below");
 969   int vtable_offset_in_bytes = base + vtableEntry::method_offset_in_bytes();
 970 
 971   if (vtable_index.is_register()) {
 972     lea(method_result, Address(recv_klass,
 973                                vtable_index.as_register(),
 974                                Address::lsl(LogBytesPerWord)));
 975     ldr(method_result, Address(method_result, vtable_offset_in_bytes));
 976   } else {
 977     vtable_offset_in_bytes += vtable_index.as_constant() * wordSize;
 978     ldr(method_result, Address(recv_klass, vtable_offset_in_bytes));
 979   }
 980 }
 981 
 982 void MacroAssembler::check_klass_subtype(Register sub_klass,
 983                            Register super_klass,
 984                            Register temp_reg,
 985                            Label& L_success) {
 986   Label L_failure;




 881   else
 882     Assembler:: notify(type);
 883 }
 884 
 885 // Look up the method for a megamorphic invokeinterface call.
 886 // The target method is determined by <intf_klass, itable_index>.
 887 // The receiver klass is in recv_klass.
 888 // On success, the result will be in method_result, and execution falls through.
 889 // On failure, execution transfers to the given label.
 890 void MacroAssembler::lookup_interface_method(Register recv_klass,
 891                                              Register intf_klass,
 892                                              RegisterOrConstant itable_index,
 893                                              Register method_result,
 894                                              Register scan_temp,
 895                                              Label& L_no_such_interface) {
 896   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
 897   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
 898          "caller must use same register for non-constant itable index as for method");
 899 
 900   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
 901   int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
 902   int itentry_off = itableMethodEntry::method_offset_in_bytes();
 903   int scan_step   = itableOffsetEntry::size() * wordSize;
 904   int vte_size    = vtableEntry::size_in_bytes();
 905   assert(vte_size == wordSize, "else adjust times_vte_scale");
 906 
 907   ldrw(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset()));
 908 
 909   // %%% Could store the aligned, prescaled offset in the klassoop.
 910   // lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
 911   lea(scan_temp, Address(recv_klass, scan_temp, Address::lsl(3)));
 912   add(scan_temp, scan_temp, vtable_base);
 913   if (HeapWordsPerLong > 1) {
 914     // Round up to align_object_offset boundary
 915     // see code for instanceKlass::start_of_itable!
 916     round_to(scan_temp, BytesPerLong);
 917   }
 918 
 919   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
 920   assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
 921   // lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
 922   lea(recv_klass, Address(recv_klass, itable_index, Address::lsl(3)));
 923   if (itentry_off)
 924     add(recv_klass, recv_klass, itentry_off);
 925 
 926   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
 927   //   if (scan->interface() == intf) {


 946     bind(search);
 947 
 948     // Check that the previous entry is non-null.  A null entry means that
 949     // the receiver class doesn't implement the interface, and wasn't the
 950     // same as when the caller was compiled.
 951     cbz(method_result, L_no_such_interface);
 952     add(scan_temp, scan_temp, scan_step);
 953   }
 954 
 955   bind(found_method);
 956 
 957   // Got a hit.
 958   ldr(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
 959   ldr(method_result, Address(recv_klass, scan_temp));
 960 }
 961 
 962 // virtual method calling
 963 void MacroAssembler::lookup_virtual_method(Register recv_klass,
 964                                            RegisterOrConstant vtable_index,
 965                                            Register method_result) {
 966   const int base = in_bytes(InstanceKlass::vtable_start_offset());
 967   assert(vtableEntry::size() * wordSize == 8,
 968          "adjust the scaling in the code below");
 969   int vtable_offset_in_bytes = base + vtableEntry::method_offset_in_bytes();
 970 
 971   if (vtable_index.is_register()) {
 972     lea(method_result, Address(recv_klass,
 973                                vtable_index.as_register(),
 974                                Address::lsl(LogBytesPerWord)));
 975     ldr(method_result, Address(method_result, vtable_offset_in_bytes));
 976   } else {
 977     vtable_offset_in_bytes += vtable_index.as_constant() * wordSize;
 978     ldr(method_result, Address(recv_klass, vtable_offset_in_bytes));
 979   }
 980 }
 981 
 982 void MacroAssembler::check_klass_subtype(Register sub_klass,
 983                            Register super_klass,
 984                            Register temp_reg,
 985                            Label& L_success) {
 986   Label L_failure;


< prev index next >