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