src/cpu/x86/vm/assembler_x86.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-dvm Sdiff src/cpu/x86/vm

src/cpu/x86/vm/assembler_x86.cpp

Print this page
rev 522 : [mq]: meth.patch


6227     movb(dst, src);
6228   }
6229   return off;
6230 }
6231 
6232 int MacroAssembler::load_unsigned_word(Register dst, Address src) {
6233   // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16,
6234   // and "3.9 Partial Register Penalties", p. 22).
6235   int off;
6236   if (LP64_ONLY(true ||) VM_Version::is_P6() || src.uses(dst)) {
6237     off = offset();
6238     movzwl(dst, src); // movzxw
6239   } else {
6240     xorl(dst, dst);
6241     off = offset();
6242     movw(dst, src);
6243   }
6244   return off;
6245 }
6246 






















6247 void MacroAssembler::mov32(AddressLiteral dst, Register src) {
6248   if (reachable(dst)) {
6249     movl(as_Address(dst), src);
6250   } else {
6251     lea(rscratch1, dst);
6252     movl(Address(rscratch1, 0), src);
6253   }
6254 }
6255 
6256 void MacroAssembler::mov32(Register dst, AddressLiteral src) {
6257   if (reachable(src)) {
6258     movl(dst, as_Address(src));
6259   } else {
6260     lea(rscratch1, src);
6261     movl(dst, Address(rscratch1, 0));
6262   }
6263 }
6264 
6265 // C++ bool manipulation
6266 


7077 
7078 void MacroAssembler::verify_oop(Register reg, const char* s) {
7079   if (!VerifyOops) return;
7080 
7081   // Pass register number to verify_oop_subroutine
7082   char* b = new char[strlen(s) + 50];
7083   sprintf(b, "verify_oop: %s: %s", reg->name(), s);
7084   push(rax);                          // save rax,
7085   push(reg);                          // pass register argument
7086   ExternalAddress buffer((address) b);
7087   // avoid using pushptr, as it modifies scratch registers
7088   // and our contract is not to modify anything
7089   movptr(rax, buffer.addr());
7090   push(rax);
7091   // call indirectly to solve generation ordering problem
7092   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
7093   call(rax);
7094 }
7095 
7096 











































































































































































































































7097 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
7098   if (!VerifyOops) return;
7099 
7100   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
7101   // Pass register number to verify_oop_subroutine
7102   char* b = new char[strlen(s) + 50];
7103   sprintf(b, "verify_oop_addr: %s", s);
7104 
7105   push(rax);                          // save rax,
7106   // addr may contain rsp so we will have to adjust it based on the push
7107   // we just did
7108   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
7109   // stores rax into addr which is backwards of what was intended.
7110   if (addr.uses(rsp)) {
7111     lea(rax, addr);
7112     pushptr(Address(rax, BytesPerWord));
7113   } else {
7114     pushptr(addr);
7115   }
7116 




6227     movb(dst, src);
6228   }
6229   return off;
6230 }
6231 
6232 int MacroAssembler::load_unsigned_word(Register dst, Address src) {
6233   // According to Intel Doc. AP-526, "Zero-Extension of Short", p.16,
6234   // and "3.9 Partial Register Penalties", p. 22).
6235   int off;
6236   if (LP64_ONLY(true ||) VM_Version::is_P6() || src.uses(dst)) {
6237     off = offset();
6238     movzwl(dst, src); // movzxw
6239   } else {
6240     xorl(dst, dst);
6241     off = offset();
6242     movw(dst, src);
6243   }
6244   return off;
6245 }
6246 
6247 void MacroAssembler::load_sized_value(Register dst, Address src,
6248                                       int size_in_bytes, bool is_signed) {
6249   switch (size_in_bytes ^ (is_signed ? -1 : 0)) {
6250 #ifndef _LP64
6251   // For case 8, caller is responsible for manually loading
6252   // the high word into another register.
6253   case ~8:  // fall through:
6254   case  8:  movl(               dst, src ); break;
6255 #else
6256   case ~8:  // fall through:
6257   case  8:  movq(               dst, src ); break;
6258 #endif
6259   case ~4:  // fall through:
6260   case  4:  movl(               dst, src ); break;
6261   case ~2:  load_signed_word(   dst, src ); break;
6262   case  2:  load_unsigned_word( dst, src ); break;
6263   case ~1:  load_signed_byte(   dst, src ); break;
6264   case  1:  load_unsigned_byte( dst, src ); break;
6265   default:  ShouldNotReachHere();
6266   }
6267 }
6268 
6269 void MacroAssembler::mov32(AddressLiteral dst, Register src) {
6270   if (reachable(dst)) {
6271     movl(as_Address(dst), src);
6272   } else {
6273     lea(rscratch1, dst);
6274     movl(Address(rscratch1, 0), src);
6275   }
6276 }
6277 
6278 void MacroAssembler::mov32(Register dst, AddressLiteral src) {
6279   if (reachable(src)) {
6280     movl(dst, as_Address(src));
6281   } else {
6282     lea(rscratch1, src);
6283     movl(dst, Address(rscratch1, 0));
6284   }
6285 }
6286 
6287 // C++ bool manipulation
6288 


7099 
7100 void MacroAssembler::verify_oop(Register reg, const char* s) {
7101   if (!VerifyOops) return;
7102 
7103   // Pass register number to verify_oop_subroutine
7104   char* b = new char[strlen(s) + 50];
7105   sprintf(b, "verify_oop: %s: %s", reg->name(), s);
7106   push(rax);                          // save rax,
7107   push(reg);                          // pass register argument
7108   ExternalAddress buffer((address) b);
7109   // avoid using pushptr, as it modifies scratch registers
7110   // and our contract is not to modify anything
7111   movptr(rax, buffer.addr());
7112   push(rax);
7113   // call indirectly to solve generation ordering problem
7114   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
7115   call(rax);
7116 }
7117 
7118 
7119 RegisterConstant MacroAssembler::delayed_value(intptr_t* delayed_value_addr, Register tmp) {
7120   intptr_t value = *delayed_value_addr;
7121   if (value != 0)
7122     return value;
7123   movptr(tmp, ExternalAddress((address) delayed_value_addr));
7124 #ifdef ASSERT
7125   Label L;
7126   testl(tmp, tmp);
7127   jccb(Assembler::notZero, L);
7128   hlt();
7129   bind(L);
7130 #endif
7131   return tmp;
7132 }
7133 
7134 
7135 void MacroAssembler::lookup_interface_method(Register recv_klass,
7136                                              Register intf_klass,
7137                                              RegisterConstant itable_index,
7138                                              Register method_result,
7139                                              Register scan_temp,
7140                                              Label& L_no_such_interface) {
7141   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
7142   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
7143          "caller must use same register for non-constant itable index as for method");
7144 
7145   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
7146   int vtable_base = instanceKlass::vtable_start_offset() * wordSize;
7147   int scan_step   = itableOffsetEntry::size() * wordSize;
7148   int vte_size    = vtableEntry::size() * wordSize;
7149   Address::ScaleFactor times_vte_scale = Address::times_ptr;
7150   assert(vte_size == wordSize, "else adjust times_vte_scale");
7151 
7152   movl(scan_temp, Address(recv_klass, instanceKlass::vtable_length_offset() * wordSize));
7153   lea( scan_temp, Address(recv_klass, scan_temp, times_vte_scale, vtable_base));
7154   if (HeapWordsPerLong > 1) {
7155     // Round up to align_object_offset boundary
7156     round_to(scan_temp, BytesPerLong);
7157   }
7158 
7159   // Adjust recv_klass by scaled itable_index, so we can free itable_index.
7160   assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
7161   lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr));
7162 
7163   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
7164   //   if (scan->interface() == intf) {
7165   //     result = (klass + scan->offset() + itable_index);
7166   //   }
7167   // }
7168   Label search, found_method;
7169 
7170   for (int peel = 1; peel >= 0; peel--) {
7171     movptr(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
7172     cmpptr(intf_klass, method_result);
7173     jccb(Assembler::notEqual, search);
7174 
7175     // Got a hit.
7176     movl(method_result, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
7177     movptr(method_result, Address(recv_klass, method_result, Address::times_1));
7178 
7179     if (!peel)  break;
7180     jmp(found_method);
7181 
7182     bind(search);
7183     // Check that the previous entry is non-null.  A null entry means that
7184     // the reciever class doesn't implement the interface, and wasn't the
7185     // same as when the caller was compiled.
7186     testptr(method_result, method_result);
7187     jcc(Assembler::zero, L_no_such_interface);
7188     addptr(scan_temp, scan_step);
7189   }
7190 
7191   bind(found_method);
7192 }
7193 
7194 
7195 // Test sub_klass against super_klass.
7196 // Fall through on failure, but branch to L_success if there is a match.
7197 // Use up the given temp_reg, but don't kill any other register.
7198 // Update the sub's secondary super cache if necesary.
7199 void MacroAssembler::check_klass_subtype(Register sub_klass,
7200                                          Register super_klass,
7201                                          Register temp_reg,
7202                                          Label& L_success) {
7203   Label L_failure;              // fallthrough label
7204 
7205   assert_different_registers(sub_klass, super_klass, temp_reg);
7206 
7207   // a couple of useful fields in sub_klass:
7208   int ss_offset = (klassOopDesc::header_size() * HeapWordSize +
7209                    Klass::secondary_supers_offset_in_bytes());
7210   int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
7211                    Klass::secondary_super_cache_offset_in_bytes());
7212   Address secondary_supers_addr(sub_klass, ss_offset);
7213   Address super_cache_addr(     sub_klass, sc_offset);
7214 
7215   int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
7216                     Klass::super_check_offset_offset_in_bytes());
7217   Address super_check_offset_addr(super_klass, sco_offset);
7218 
7219   // if the pointers are equal, we are done (e.g., String[] elements)
7220   cmpptr(sub_klass, super_klass);
7221   jcc(Assembler::equal, L_success);
7222 
7223   // check the supertype display:
7224   movl(temp_reg, super_check_offset_addr);
7225   Address super_check_addr(sub_klass, temp_reg, Address::times_1, 0);
7226   cmpptr(super_klass, super_check_addr); // load displayed supertype
7227   jcc(Assembler::equal, L_success);
7228 
7229   // if it was a primary super, we can just fail immediately
7230   cmpl(temp_reg, sc_offset);
7231   jcc(Assembler::notEqual, L_failure);
7232 
7233   // Now do a linear scan of the secondary super-klass chain.
7234   // This code is rarely used, so simplicity is a virtue here.
7235   {
7236     // The repne_scan instruction uses fixed registers, which we must spill.
7237     // Don't bother to figure out pre-existing connections with the input regs.
7238     push(rax);
7239     push(rcx);
7240     push(rdi);
7241     push(super_klass);
7242 
7243     movptr(rdi, secondary_supers_addr);
7244     // Load the array length.
7245     movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
7246     // Skip to start of data.
7247     addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
7248     // Scan rcx words at [edi] for occurance of rax,
7249     // Set NZ/Z based on last compare
7250     pop(rax);   // super_klass value, even if it was in rdi or rcx
7251 
7252 
7253 #ifdef _LP64
7254     // This part is tricky, as values in supers array could be 32 or 64 bit wide
7255     // and we store values in objArrays always encoded, thus we need to encode
7256     // the value of rax before repne.  Note that rax is dead after the repne.
7257     if (UseCompressedOops) {
7258       encode_heap_oop_not_null(rax);
7259       repne_scanl();
7260     } else
7261 #endif // _LP64
7262       repne_scan();
7263 
7264     // Unspill the temp. registers:
7265     pop(rdi);
7266     pop(rcx);
7267     pop(rax);
7268   }
7269   jcc(Assembler::notEqual, L_failure);
7270 
7271   // Success.  Cache the super we found and proceed in triumph.
7272   movptr(super_cache_addr, super_klass);
7273 
7274   jmp(L_success);
7275 
7276   // Fall through on failure!
7277   bind(L_failure);
7278 }
7279 
7280 
7281 // registers on entry:
7282 //  - rax ('check' register): required MethodType
7283 //  - rcx: method handle
7284 //  - rdx, rsi, or ?: killable temp
7285 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
7286                                               Register temp_reg,
7287                                               Label& wrong_method_type) {
7288   if (UseCompressedOops)  unimplemented();  // field accesses must decode
7289   // compare method type against that of the receiver
7290   cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
7291   jcc(Assembler::notEqual, wrong_method_type);
7292 }
7293 
7294 
7295 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
7296                                                 Register temp_reg) {
7297   if (UseCompressedOops)  unimplemented();  // field accesses must decode
7298   // load mh.type.form.vmslots
7299   if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
7300     // hoist vmslots into every mh to avoid dependent load chain
7301     movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
7302   } else {
7303     Register temp2_reg = vmslots_reg;
7304     movptr(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
7305     movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
7306     movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
7307   }
7308 }
7309 
7310 
7311 // registers on entry:
7312 //  - rcx: method handle
7313 //  - rdx: killable temp (interpreted only)
7314 //  - rax: killable temp (compiled only)
7315 void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) {
7316   assert(mh_reg == rcx, "caller must put MH object in rcx");
7317   assert_different_registers(mh_reg, temp_reg);
7318 
7319   if (UseCompressedOops)  unimplemented();  // field accesses must decode
7320 
7321   // pick out the interpreted side of the handler
7322   movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
7323 
7324   // off we go...
7325   jmp(Address(temp_reg, MethodEntry::from_interpreted_entry_offset_in_bytes()));
7326 
7327   // for the various stubs which take control at this point,
7328   // see MethodHandles::generate_method_handle_stub
7329 }
7330 
7331 
7332 Address MacroAssembler::argument_address(RegisterConstant arg_slot,
7333                                          int extra_slot_offset) {
7334   // cf. TemplateTable::prepare_invoke(), if (load_receiver).
7335   int stackElementSize = Interpreter::stackElementSize();
7336   int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
7337 #ifdef ASSERT
7338   int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
7339   assert(offset1 - offset == stackElementSize, "correct arithmetic");
7340 #endif
7341   Register             scale_reg    = noreg;
7342   Address::ScaleFactor scale_factor = Address::no_scale;
7343   if (arg_slot.is_constant()) {
7344     offset += arg_slot.as_constant() * stackElementSize;
7345   } else {
7346     scale_reg    = arg_slot.as_register();
7347     scale_factor = Address::times(stackElementSize);
7348   }
7349   offset += wordSize;           // return PC is on stack
7350   return Address(rsp, scale_reg, scale_factor, offset);
7351 }
7352 
7353 
7354 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
7355   if (!VerifyOops) return;
7356 
7357   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
7358   // Pass register number to verify_oop_subroutine
7359   char* b = new char[strlen(s) + 50];
7360   sprintf(b, "verify_oop_addr: %s", s);
7361 
7362   push(rax);                          // save rax,
7363   // addr may contain rsp so we will have to adjust it based on the push
7364   // we just did
7365   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
7366   // stores rax into addr which is backwards of what was intended.
7367   if (addr.uses(rsp)) {
7368     lea(rax, addr);
7369     pushptr(Address(rax, BytesPerWord));
7370   } else {
7371     pushptr(addr);
7372   }
7373 


src/cpu/x86/vm/assembler_x86.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File