Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/assembler_x86.cpp @ 1684:66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
Summary: set Z = 0 (not equal) before repne_scan() to indicate that class was not found when RCX == 0.
Reviewed-by: never, phh
author | kvn |
---|---|
date | Fri, 30 Jul 2010 10:21:15 -0700 |
parents | 02e771df338e |
children | 36519c19beeb |
comparison
equal
deleted
inserted
replaced
1683:99ceb0e99c9e | 1684:66c5dadb4d61 |
---|---|
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"); |