hotspot/src/cpu/x86/vm/assembler_x86.cpp
changeset 2149 3d362637b307
parent 2148 09c7f703773b
child 2150 0d91d17158cc
equal deleted inserted replaced
2148:09c7f703773b 2149:3d362637b307
  7074     pop(tmp);
  7074     pop(tmp);
  7075   }
  7075   }
  7076 }
  7076 }
  7077 
  7077 
  7078 
  7078 
       
  7079 // Look up the method for a megamorphic invokeinterface call.
       
  7080 // The target method is determined by <intf_klass, itable_index>.
       
  7081 // The receiver klass is in recv_klass.
       
  7082 // On success, the result will be in method_result, and execution falls through.
       
  7083 // On failure, execution transfers to the given label.
       
  7084 void MacroAssembler::lookup_interface_method(Register recv_klass,
       
  7085                                              Register intf_klass,
       
  7086                                              RegisterConstant itable_index,
       
  7087                                              Register method_result,
       
  7088                                              Register scan_temp,
       
  7089                                              Label& L_no_such_interface) {
       
  7090   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
       
  7091   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
       
  7092          "caller must use same register for non-constant itable index as for method");
       
  7093 
       
  7094   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
       
  7095   int vtable_base = instanceKlass::vtable_start_offset() * wordSize;
       
  7096   int itentry_off = itableMethodEntry::method_offset_in_bytes();
       
  7097   int scan_step   = itableOffsetEntry::size() * wordSize;
       
  7098   int vte_size    = vtableEntry::size() * wordSize;
       
  7099   Address::ScaleFactor times_vte_scale = Address::times_ptr;
       
  7100   assert(vte_size == wordSize, "else adjust times_vte_scale");
       
  7101 
       
  7102   movl(scan_temp, Address(recv_klass, instanceKlass::vtable_length_offset() * wordSize));
       
  7103 
       
  7104   // %%% Could store the aligned, prescaled offset in the klassoop.
       
  7105   lea(scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
       
  7106   if (HeapWordsPerLong > 1) {
       
  7107     // Round up to align_object_offset boundary
       
  7108     // see code for instanceKlass::start_of_itable!
       
  7109     round_to(scan_temp, BytesPerLong);
       
  7110   }
       
  7111 
       
  7112   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
       
  7113   assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
       
  7114   lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
       
  7115 
       
  7116   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
       
  7117   //   if (scan->interface() == intf) {
       
  7118   //     result = (klass + scan->offset() + itable_index);
       
  7119   //   }
       
  7120   // }
       
  7121   Label search, found_method;
       
  7122 
       
  7123   for (int peel = 1; peel >= 0; peel--) {
       
  7124     movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
       
  7125     cmpptr(intf_klass, method_result);
       
  7126 
       
  7127     if (peel) {
       
  7128       jccb(Assembler::equal, found_method);
       
  7129     } else {
       
  7130       jccb(Assembler::notEqual, search);
       
  7131       // (invert the test to fall through to found_method...)
       
  7132     }
       
  7133 
       
  7134     if (!peel)  break;
       
  7135 
       
  7136     bind(search);
       
  7137 
       
  7138     // Check that the previous entry is non-null.  A null entry means that
       
  7139     // the receiver class doesn't implement the interface, and wasn't the
       
  7140     // same as when the caller was compiled.
       
  7141     testptr(method_result, method_result);
       
  7142     jcc(Assembler::zero, L_no_such_interface);
       
  7143     addptr(scan_temp, scan_step);
       
  7144   }
       
  7145 
       
  7146   bind(found_method);
       
  7147 
       
  7148   // Got a hit.
       
  7149   movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
       
  7150   movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
       
  7151 }
       
  7152 
       
  7153 
  7079 void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) {
  7154 void MacroAssembler::ucomisd(XMMRegister dst, AddressLiteral src) {
  7080   ucomisd(dst, as_Address(src));
  7155   ucomisd(dst, as_Address(src));
  7081 }
  7156 }
  7082 
  7157 
  7083 void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) {
  7158 void MacroAssembler::ucomiss(XMMRegister dst, AddressLiteral src) {