6022 }
6023 }
6024
6025
6026 // Look up the method for a megamorphic invokeinterface call.
6027 // The target method is determined by <intf_klass, itable_index>.
6028 // The receiver klass is in recv_klass.
6029 // On success, the result will be in method_result, and execution falls through.
6030 // On failure, execution transfers to the given label.
6031 void MacroAssembler::lookup_interface_method(Register recv_klass,
6032 Register intf_klass,
6033 RegisterOrConstant itable_index,
6034 Register method_result,
6035 Register scan_temp,
6036 Label& L_no_such_interface) {
6037 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
6038 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
6039 "caller must use same register for non-constant itable index as for method");
6040
6041 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
6042 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
6043 int itentry_off = itableMethodEntry::method_offset_in_bytes();
6044 int scan_step = itableOffsetEntry::size() * wordSize;
6045 int vte_size = vtableEntry::size() * wordSize;
6046 Address::ScaleFactor times_vte_scale = Address::times_ptr;
6047 assert(vte_size == wordSize, "else adjust times_vte_scale");
6048
6049 movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize));
6050
6051 // %%% Could store the aligned, prescaled offset in the klassoop.
6052 lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
6053 if (HeapWordsPerLong > 1) {
6054 // Round up to align_object_offset boundary
6055 // see code for InstanceKlass::start_of_itable!
6056 round_to(scan_temp, BytesPerLong);
6057 }
6058
6059 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
6060 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
6061 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
6062
6063 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
6064 // if (scan->interface() == intf) {
6065 // result = (klass + scan->offset() + itable_index);
6066 // }
6067 // }
6068 Label search, found_method;
6069
6085 // Check that the previous entry is non-null. A null entry means that
6086 // the receiver class doesn't implement the interface, and wasn't the
6087 // same as when the caller was compiled.
6088 testptr(method_result, method_result);
6089 jcc(Assembler::zero, L_no_such_interface);
6090 addptr(scan_temp, scan_step);
6091 }
6092
6093 bind(found_method);
6094
6095 // Got a hit.
6096 movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
6097 movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
6098 }
6099
6100
6101 // virtual method calling
6102 void MacroAssembler::lookup_virtual_method(Register recv_klass,
6103 RegisterOrConstant vtable_index,
6104 Register method_result) {
6105 const int base = InstanceKlass::vtable_start_offset() * wordSize;
6106 assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
6107 Address vtable_entry_addr(recv_klass,
6108 vtable_index, Address::times_ptr,
6109 base + vtableEntry::method_offset_in_bytes());
6110 movptr(method_result, vtable_entry_addr);
6111 }
6112
6113
6114 void MacroAssembler::check_klass_subtype(Register sub_klass,
6115 Register super_klass,
6116 Register temp_reg,
6117 Label& L_success) {
6118 Label L_failure;
6119 check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, &L_success, &L_failure, NULL);
6120 check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, noreg, &L_success, NULL);
6121 bind(L_failure);
6122 }
6123
6124
6125 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
|
6022 }
6023 }
6024
6025
6026 // Look up the method for a megamorphic invokeinterface call.
6027 // The target method is determined by <intf_klass, itable_index>.
6028 // The receiver klass is in recv_klass.
6029 // On success, the result will be in method_result, and execution falls through.
6030 // On failure, execution transfers to the given label.
6031 void MacroAssembler::lookup_interface_method(Register recv_klass,
6032 Register intf_klass,
6033 RegisterOrConstant itable_index,
6034 Register method_result,
6035 Register scan_temp,
6036 Label& L_no_such_interface) {
6037 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
6038 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
6039 "caller must use same register for non-constant itable index as for method");
6040
6041 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
6042 int vtable_base = in_bytes(InstanceKlass::vtable_start_offset());
6043 int itentry_off = itableMethodEntry::method_offset_in_bytes();
6044 int scan_step = itableOffsetEntry::size() * wordSize;
6045 int vte_size = vtableEntry::size_in_bytes();
6046 Address::ScaleFactor times_vte_scale = Address::times_ptr;
6047 assert(vte_size == wordSize, "else adjust times_vte_scale");
6048
6049 movl(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset()));
6050
6051 // %%% Could store the aligned, prescaled offset in the klassoop.
6052 lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
6053 if (HeapWordsPerLong > 1) {
6054 // Round up to align_object_offset boundary
6055 // see code for InstanceKlass::start_of_itable!
6056 round_to(scan_temp, BytesPerLong);
6057 }
6058
6059 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
6060 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
6061 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
6062
6063 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
6064 // if (scan->interface() == intf) {
6065 // result = (klass + scan->offset() + itable_index);
6066 // }
6067 // }
6068 Label search, found_method;
6069
6085 // Check that the previous entry is non-null. A null entry means that
6086 // the receiver class doesn't implement the interface, and wasn't the
6087 // same as when the caller was compiled.
6088 testptr(method_result, method_result);
6089 jcc(Assembler::zero, L_no_such_interface);
6090 addptr(scan_temp, scan_step);
6091 }
6092
6093 bind(found_method);
6094
6095 // Got a hit.
6096 movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
6097 movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
6098 }
6099
6100
6101 // virtual method calling
6102 void MacroAssembler::lookup_virtual_method(Register recv_klass,
6103 RegisterOrConstant vtable_index,
6104 Register method_result) {
6105 const int base = in_bytes(InstanceKlass::vtable_start_offset());
6106 assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
6107 Address vtable_entry_addr(recv_klass,
6108 vtable_index, Address::times_ptr,
6109 base + vtableEntry::method_offset_in_bytes());
6110 movptr(method_result, vtable_entry_addr);
6111 }
6112
6113
6114 void MacroAssembler::check_klass_subtype(Register sub_klass,
6115 Register super_klass,
6116 Register temp_reg,
6117 Label& L_success) {
6118 Label L_failure;
6119 check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, &L_success, &L_failure, NULL);
6120 check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, noreg, &L_success, NULL);
6121 bind(L_failure);
6122 }
6123
6124
6125 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
|