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"); |