hotspot/src/cpu/x86/vm/assembler_x86.cpp
changeset 6179 4846648c4b7b
parent 5706 0c91076143f9
child 6185 1d2b3c0c9674
equal deleted inserted replaced
6178:bfbfaacd23e5 6179:4846648c4b7b
  7566   // Skip to start of data.
  7566   // Skip to start of data.
  7567   addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
  7567   addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
  7568 
  7568 
  7569   // Scan RCX words at [RDI] for an occurrence of RAX.
  7569   // Scan RCX words at [RDI] for an occurrence of RAX.
  7570   // Set NZ/Z based on last compare.
  7570   // Set NZ/Z based on last compare.
       
  7571   // Z flag value will not be set by 'repne' if RCX == 0 since 'repne' does
       
  7572   // not change flags (only scas instruction which is repeated sets flags).
       
  7573   // Set Z = 0 (not equal) before 'repne' to indicate that class was not found.
  7571 #ifdef _LP64
  7574 #ifdef _LP64
  7572   // This part is tricky, as values in supers array could be 32 or 64 bit wide
  7575   // This part is tricky, as values in supers array could be 32 or 64 bit wide
  7573   // and we store values in objArrays always encoded, thus we need to encode
  7576   // and we store values in objArrays always encoded, thus we need to encode
  7574   // the value of rax before repne.  Note that rax is dead after the repne.
  7577   // the value of rax before repne.  Note that rax is dead after the repne.
  7575   if (UseCompressedOops) {
  7578   if (UseCompressedOops) {
  7576     encode_heap_oop_not_null(rax);
  7579     encode_heap_oop_not_null(rax); // Changes flags.
  7577     // The superclass is never null; it would be a basic system error if a null
  7580     // The superclass is never null; it would be a basic system error if a null
  7578     // pointer were to sneak in here.  Note that we have already loaded the
  7581     // pointer were to sneak in here.  Note that we have already loaded the
  7579     // Klass::super_check_offset from the super_klass in the fast path,
  7582     // Klass::super_check_offset from the super_klass in the fast path,
  7580     // so if there is a null in that register, we are already in the afterlife.
  7583     // so if there is a null in that register, we are already in the afterlife.
       
  7584     testl(rax,rax); // Set Z = 0
  7581     repne_scanl();
  7585     repne_scanl();
  7582   } else
  7586   } else
  7583 #endif // _LP64
  7587 #endif // _LP64
       
  7588   {
       
  7589     testptr(rax,rax); // Set Z = 0
  7584     repne_scan();
  7590     repne_scan();
  7585 
  7591   }
  7586   // Unspill the temp. registers:
  7592   // Unspill the temp. registers:
  7587   if (pushed_rdi)  pop(rdi);
  7593   if (pushed_rdi)  pop(rdi);
  7588   if (pushed_rcx)  pop(rcx);
  7594   if (pushed_rcx)  pop(rcx);
  7589   if (pushed_rax)  pop(rax);
  7595   if (pushed_rax)  pop(rax);
  7590 
  7596 
  8255   } else {
  8261   } else {
  8256     movslq(dst, (int32_t)NULL_WORD);
  8262     movslq(dst, (int32_t)NULL_WORD);
  8257   }
  8263   }
  8258 }
  8264 }
  8259 
  8265 
       
  8266 #ifdef ASSERT
       
  8267 void MacroAssembler::verify_heapbase(const char* msg) {
       
  8268   assert (UseCompressedOops, "should be compressed");
       
  8269   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  8270   if (CheckCompressedOops) {
       
  8271     Label ok;
       
  8272     push(rscratch1); // cmpptr trashes rscratch1
       
  8273     cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
       
  8274     jcc(Assembler::equal, ok);
       
  8275     stop(msg);
       
  8276     bind(ok);
       
  8277     pop(rscratch1);
       
  8278   }
       
  8279 }
       
  8280 #endif
       
  8281 
  8260 // Algorithm must match oop.inline.hpp encode_heap_oop.
  8282 // Algorithm must match oop.inline.hpp encode_heap_oop.
  8261 void MacroAssembler::encode_heap_oop(Register r) {
  8283 void MacroAssembler::encode_heap_oop(Register r) {
  8262   assert (UseCompressedOops, "should be compressed");
  8284 #ifdef ASSERT
  8263   assert (Universe::heap() != NULL, "java heap should be initialized");
  8285   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
       
  8286 #endif
       
  8287   verify_oop(r, "broken oop in encode_heap_oop");
  8264   if (Universe::narrow_oop_base() == NULL) {
  8288   if (Universe::narrow_oop_base() == NULL) {
  8265     verify_oop(r, "broken oop in encode_heap_oop");
       
  8266     if (Universe::narrow_oop_shift() != 0) {
  8289     if (Universe::narrow_oop_shift() != 0) {
  8267       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
  8290       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
  8268       shrq(r, LogMinObjAlignmentInBytes);
  8291       shrq(r, LogMinObjAlignmentInBytes);
  8269     }
  8292     }
  8270     return;
  8293     return;
  8271   }
  8294   }
  8272 #ifdef ASSERT
       
  8273   if (CheckCompressedOops) {
       
  8274     Label ok;
       
  8275     push(rscratch1); // cmpptr trashes rscratch1
       
  8276     cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
       
  8277     jcc(Assembler::equal, ok);
       
  8278     stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
       
  8279     bind(ok);
       
  8280     pop(rscratch1);
       
  8281   }
       
  8282 #endif
       
  8283   verify_oop(r, "broken oop in encode_heap_oop");
       
  8284   testq(r, r);
  8295   testq(r, r);
  8285   cmovq(Assembler::equal, r, r12_heapbase);
  8296   cmovq(Assembler::equal, r, r12_heapbase);
  8286   subq(r, r12_heapbase);
  8297   subq(r, r12_heapbase);
  8287   shrq(r, LogMinObjAlignmentInBytes);
  8298   shrq(r, LogMinObjAlignmentInBytes);
  8288 }
  8299 }
  8289 
  8300 
  8290 void MacroAssembler::encode_heap_oop_not_null(Register r) {
  8301 void MacroAssembler::encode_heap_oop_not_null(Register r) {
  8291   assert (UseCompressedOops, "should be compressed");
       
  8292   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  8293 #ifdef ASSERT
  8302 #ifdef ASSERT
       
  8303   verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
  8294   if (CheckCompressedOops) {
  8304   if (CheckCompressedOops) {
  8295     Label ok;
  8305     Label ok;
  8296     testq(r, r);
  8306     testq(r, r);
  8297     jcc(Assembler::notEqual, ok);
  8307     jcc(Assembler::notEqual, ok);
  8298     stop("null oop passed to encode_heap_oop_not_null");
  8308     stop("null oop passed to encode_heap_oop_not_null");
  8308     shrq(r, LogMinObjAlignmentInBytes);
  8318     shrq(r, LogMinObjAlignmentInBytes);
  8309   }
  8319   }
  8310 }
  8320 }
  8311 
  8321 
  8312 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
  8322 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
  8313   assert (UseCompressedOops, "should be compressed");
       
  8314   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  8315 #ifdef ASSERT
  8323 #ifdef ASSERT
       
  8324   verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
  8316   if (CheckCompressedOops) {
  8325   if (CheckCompressedOops) {
  8317     Label ok;
  8326     Label ok;
  8318     testq(src, src);
  8327     testq(src, src);
  8319     jcc(Assembler::notEqual, ok);
  8328     jcc(Assembler::notEqual, ok);
  8320     stop("null oop passed to encode_heap_oop_not_null2");
  8329     stop("null oop passed to encode_heap_oop_not_null2");
  8333     shrq(dst, LogMinObjAlignmentInBytes);
  8342     shrq(dst, LogMinObjAlignmentInBytes);
  8334   }
  8343   }
  8335 }
  8344 }
  8336 
  8345 
  8337 void  MacroAssembler::decode_heap_oop(Register r) {
  8346 void  MacroAssembler::decode_heap_oop(Register r) {
  8338   assert (UseCompressedOops, "should be compressed");
  8347 #ifdef ASSERT
  8339   assert (Universe::heap() != NULL, "java heap should be initialized");
  8348   verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
       
  8349 #endif
  8340   if (Universe::narrow_oop_base() == NULL) {
  8350   if (Universe::narrow_oop_base() == NULL) {
  8341     if (Universe::narrow_oop_shift() != 0) {
  8351     if (Universe::narrow_oop_shift() != 0) {
  8342       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
  8352       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
  8343       shlq(r, LogMinObjAlignmentInBytes);
  8353       shlq(r, LogMinObjAlignmentInBytes);
  8344     }
  8354     }
  8345     verify_oop(r, "broken oop in decode_heap_oop");
  8355   } else {
  8346     return;
  8356     Label done;
  8347   }
  8357     shlq(r, LogMinObjAlignmentInBytes);
  8348 #ifdef ASSERT
  8358     jccb(Assembler::equal, done);
  8349   if (CheckCompressedOops) {
  8359     addq(r, r12_heapbase);
  8350     Label ok;
  8360     bind(done);
  8351     push(rscratch1);
  8361   }
  8352     cmpptr(r12_heapbase,
       
  8353            ExternalAddress((address)Universe::narrow_oop_base_addr()));
       
  8354     jcc(Assembler::equal, ok);
       
  8355     stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
       
  8356     bind(ok);
       
  8357     pop(rscratch1);
       
  8358   }
       
  8359 #endif
       
  8360 
       
  8361   Label done;
       
  8362   shlq(r, LogMinObjAlignmentInBytes);
       
  8363   jccb(Assembler::equal, done);
       
  8364   addq(r, r12_heapbase);
       
  8365 #if 0
       
  8366    // alternate decoding probably a wash.
       
  8367    testq(r, r);
       
  8368    jccb(Assembler::equal, done);
       
  8369    leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
       
  8370 #endif
       
  8371   bind(done);
       
  8372   verify_oop(r, "broken oop in decode_heap_oop");
  8362   verify_oop(r, "broken oop in decode_heap_oop");
  8373 }
  8363 }
  8374 
  8364 
  8375 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
  8365 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
  8376   // Note: it will change flags
  8366   // Note: it will change flags
  8408       shlq(dst, LogMinObjAlignmentInBytes);
  8398       shlq(dst, LogMinObjAlignmentInBytes);
  8409       if (Universe::narrow_oop_base() != NULL) {
  8399       if (Universe::narrow_oop_base() != NULL) {
  8410         addq(dst, r12_heapbase);
  8400         addq(dst, r12_heapbase);
  8411       }
  8401       }
  8412     }
  8402     }
  8413   } else if (dst != src) {
  8403   } else {
  8414     assert (Universe::narrow_oop_base() == NULL, "sanity");
  8404     assert (Universe::narrow_oop_base() == NULL, "sanity");
  8415     movq(dst, src);
  8405     if (dst != src) {
       
  8406       movq(dst, src);
       
  8407     }
  8416   }
  8408   }
  8417 }
  8409 }
  8418 
  8410 
  8419 void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
  8411 void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
  8420   assert (UseCompressedOops, "should only be used for compressed headers");
  8412   assert (UseCompressedOops, "should only be used for compressed headers");