comparison src/share/vm/compiler/oopMap.cpp @ 20969:534f0dde2810

It should be an error for an OopMap to mention a register that can't be found
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 14 Apr 2015 17:26:29 -0700
parents 7848fc12602b
children be896a1983c0
comparison
equal deleted inserted replaced
20964:56a30cfcefaf 20969:534f0dde2810
386 // derived pointer table in DerivedPointerTable::add(). 386 // derived pointer table in DerivedPointerTable::add().
387 MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag); 387 MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
388 do { 388 do {
389 omv = oms.current(); 389 omv = oms.current();
390 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 390 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
391 if ( loc != NULL ) { 391 guarantee(loc != NULL, "missing saved register");
392 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map); 392 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
393 oop *derived_loc = loc; 393 oop *derived_loc = loc;
394 oop val = *base_loc; 394 oop val = *base_loc;
395 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) { 395 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
396 // Ignore NULL oops and decoded NULL narrow oops which 396 // Ignore NULL oops and decoded NULL narrow oops which
397 // equal to Universe::narrow_oop_base when a narrow oop 397 // equal to Universe::narrow_oop_base when a narrow oop
398 // implicit null check is used in compiled code. 398 // implicit null check is used in compiled code.
399 // The narrow_oop_base could be NULL or be the address 399 // The narrow_oop_base could be NULL or be the address
400 // of the page below heap depending on compressed oops mode. 400 // of the page below heap depending on compressed oops mode.
401 } else 401 } else {
402 derived_oop_fn(base_loc, derived_loc); 402 derived_oop_fn(base_loc, derived_loc);
403 } 403 }
404 oms.next(); 404 oms.next();
405 } while (!oms.is_done()); 405 } while (!oms.is_done());
406 } 406 }
407 } 407 }
408 408
409 // We want coop, value and oop oop_types 409 // We want narrowoop and oop oop_types
410 int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value; 410 int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
411 { 411 {
412 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) { 412 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
413 omv = oms.current(); 413 omv = oms.current();
414 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 414 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
415 if ( loc != NULL ) { 415 // It should be an error if no location can be found for a
416 if ( omv.type() == OopMapValue::oop_value ) { 416 // register mentioned as contained an oop of some kind. Maybe
417 oop val = *loc; 417 // this was allowed previously because value_value items might
418 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) { 418 // be missing?
419 // Ignore NULL oops and decoded NULL narrow oops which 419 guarantee(loc != NULL, "missing saved register");
420 // equal to Universe::narrow_oop_base when a narrow oop 420 if ( omv.type() == OopMapValue::oop_value ) {
421 // implicit null check is used in compiled code. 421 oop val = *loc;
422 // The narrow_oop_base could be NULL or be the address 422 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
423 // of the page below heap depending on compressed oops mode. 423 // Ignore NULL oops and decoded NULL narrow oops which
424 continue; 424 // equal to Universe::narrow_oop_base when a narrow oop
425 } 425 // implicit null check is used in compiled code.
426 // The narrow_oop_base could be NULL or be the address
427 // of the page below heap depending on compressed oops mode.
428 continue;
429 }
426 #ifdef ASSERT 430 #ifdef ASSERT
427 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || 431 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
428 !Universe::heap()->is_in_or_null(*loc)) { 432 !Universe::heap()->is_in_or_null(*loc)) {
429 tty->print_cr("# Found non oop pointer. Dumping state at failure"); 433 tty->print_cr("# Found non oop pointer. Dumping state at failure");
430 // try to dump out some helpful debugging information 434 // try to dump out some helpful debugging information
431 trace_codeblob_maps(fr, reg_map); 435 trace_codeblob_maps(fr, reg_map);
432 omv.print(); 436 omv.print();
433 tty->print_cr("register r"); 437 tty->print_cr("register r");
434 omv.reg()->print(); 438 omv.reg()->print();
435 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc); 439 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
436 // do the real assert. 440 // do the real assert.
437 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer"); 441 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
438 } 442 }
439 #endif // ASSERT 443 #endif // ASSERT
440 oop_fn->do_oop(loc); 444 oop_fn->do_oop(loc);
441 } else if ( omv.type() == OopMapValue::narrowoop_value ) { 445 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
442 narrowOop *nl = (narrowOop*)loc; 446 narrowOop *nl = (narrowOop*)loc;
443 #ifndef VM_LITTLE_ENDIAN 447 #ifndef VM_LITTLE_ENDIAN
444 if (!omv.reg()->is_stack()) { 448 if (!omv.reg()->is_stack()) {
445 // compressed oops in registers only take up 4 bytes of an 449 // compressed oops in registers only take up 4 bytes of an
446 // 8 byte register but they are in the wrong part of the 450 // 8 byte register but they are in the wrong part of the
447 // word so adjust loc to point at the right place. 451 // word so adjust loc to point at the right place.
448 nl = (narrowOop*)((address)nl + 4); 452 nl = (narrowOop*)((address)nl + 4);
449 } 453 }
450 #endif 454 #endif
451 oop_fn->do_oop(nl); 455 oop_fn->do_oop(nl);
452 }
453 } 456 }
454 } 457 }
455 } 458 }
456 } 459 }
457 460