373 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
374 omv = oms.current();
375 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
376 // It should be an error if no location can be found for a
377 // register mentioned as contained an oop of some kind. Maybe
378 // this was allowed previously because value_value items might
379 // be missing?
380 guarantee(loc != NULL, "missing saved register");
381 if ( omv.type() == OopMapValue::oop_value ) {
382 oop val = *loc;
383 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
384 // Ignore NULL oops and decoded NULL narrow oops which
385 // equal to Universe::narrow_oop_base when a narrow oop
386 // implicit null check is used in compiled code.
387 // The narrow_oop_base could be NULL or be the address
388 // of the page below heap depending on compressed oops mode.
389 continue;
390 }
391 #ifdef ASSERT
392 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
393 !Universe::heap()->is_in_or_null(*loc)) {
394 tty->print_cr("# Found non oop pointer. Dumping state at failure");
395 // try to dump out some helpful debugging information
396 trace_codeblob_maps(fr, reg_map);
397 omv.print();
398 tty->print_cr("register r");
399 omv.reg()->print();
400 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
401 // do the real assert.
402 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
403 }
404 #endif // ASSERT
405 oop_fn->do_oop(loc);
406 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
407 narrowOop *nl = (narrowOop*)loc;
408 #ifndef VM_LITTLE_ENDIAN
409 VMReg vmReg = omv.reg();
410 // Don't do this on SPARC float registers as they can be individually addressed
411 if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
412 // compressed oops in registers only take up 4 bytes of an
413 // 8 byte register but they are in the wrong part of the
414 // word so adjust loc to point at the right place.
415 nl = (narrowOop*)((address)nl + 4);
416 }
417 #endif
418 oop_fn->do_oop(nl);
419 }
420 }
421 }
422 }
754
755
756 void DerivedPointerTable::clear() {
757 // The first time, we create the list. Otherwise it should be
758 // empty. If not, then we have probably forgotton to call
759 // update_pointers after last GC/Scavenge.
760 assert (!_active, "should not be active");
761 assert(_list == NULL || _list->length() == 0, "table not empty");
762 if (_list == NULL) {
763 _list = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<DerivedPointerEntry*>(10, true); // Allocated on C heap
764 }
765 _active = true;
766 }
767
768
769 // Returns value of location as an int
770 intptr_t value_of_loc(oop *pointer) { return cast_from_oop<intptr_t>((*pointer)); }
771
772
773 void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) {
774 assert(Universe::heap()->is_in_or_null(*base_loc), "not an oop");
775 assert(derived_loc != base_loc, "Base and derived in same location");
776 if (_active) {
777 assert(*derived_loc != (oop)base_loc, "location already added");
778 assert(_list != NULL, "list must exist");
779 intptr_t offset = value_of_loc(derived_loc) - value_of_loc(base_loc);
780 // This assert is invalid because derived pointers can be
781 // arbitrarily far away from their base.
782 // assert(offset >= -1000000, "wrong derived pointer info");
783
784 if (TraceDerivedPointers) {
785 tty->print_cr(
786 "Add derived pointer@" INTPTR_FORMAT
787 " - Derived: " INTPTR_FORMAT
788 " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: " INTX_FORMAT ")",
789 p2i(derived_loc), p2i((address)*derived_loc), p2i((address)*base_loc), p2i(base_loc), offset
790 );
791 }
792 // Set derived oop location to point to base.
793 *derived_loc = (oop)base_loc;
794 assert_lock_strong(DerivedPointerTableGC_lock);
795 DerivedPointerEntry *entry = new DerivedPointerEntry(derived_loc, offset);
796 _list->append(entry);
797 }
798 }
799
800
801 void DerivedPointerTable::update_pointers() {
802 assert(_list != NULL, "list must exist");
803 for(int i = 0; i < _list->length(); i++) {
804 DerivedPointerEntry* entry = _list->at(i);
805 oop* derived_loc = entry->location();
806 intptr_t offset = entry->offset();
807 // The derived oop was setup to point to location of base
808 oop base = **(oop**)derived_loc;
809 assert(Universe::heap()->is_in_or_null(base), "must be an oop");
810
811 *derived_loc = (oop)(((address)base) + offset);
812 assert(value_of_loc(derived_loc) - value_of_loc(&base) == offset, "sanity check");
813
814 if (TraceDerivedPointers) {
815 tty->print_cr("Updating derived pointer@" INTPTR_FORMAT
816 " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: " INTX_FORMAT ")",
817 p2i(derived_loc), p2i((address)*derived_loc), p2i((address)base), offset);
818 }
819
820 // Delete entry
821 delete entry;
822 _list->at_put(i, NULL);
823 }
824 // Clear list, so it is ready for next traversal (this is an invariant)
825 if (TraceDerivedPointers && !_list->is_empty()) {
826 tty->print_cr("--------------------------");
827 }
828 _list->clear();
829 _active = false;
|
373 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
374 omv = oms.current();
375 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
376 // It should be an error if no location can be found for a
377 // register mentioned as contained an oop of some kind. Maybe
378 // this was allowed previously because value_value items might
379 // be missing?
380 guarantee(loc != NULL, "missing saved register");
381 if ( omv.type() == OopMapValue::oop_value ) {
382 oop val = *loc;
383 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
384 // Ignore NULL oops and decoded NULL narrow oops which
385 // equal to Universe::narrow_oop_base when a narrow oop
386 // implicit null check is used in compiled code.
387 // The narrow_oop_base could be NULL or be the address
388 // of the page below heap depending on compressed oops mode.
389 continue;
390 }
391 #ifdef ASSERT
392 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
393 !GC::gc()->heap()->is_in_or_null(*loc)) {
394 tty->print_cr("# Found non oop pointer. Dumping state at failure");
395 // try to dump out some helpful debugging information
396 trace_codeblob_maps(fr, reg_map);
397 omv.print();
398 tty->print_cr("register r");
399 omv.reg()->print();
400 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
401 // do the real assert.
402 assert(GC::gc()->heap()->is_in_or_null(*loc), "found non oop pointer");
403 }
404 #endif // ASSERT
405 oop_fn->do_oop(loc);
406 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
407 narrowOop *nl = (narrowOop*)loc;
408 #ifndef VM_LITTLE_ENDIAN
409 VMReg vmReg = omv.reg();
410 // Don't do this on SPARC float registers as they can be individually addressed
411 if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
412 // compressed oops in registers only take up 4 bytes of an
413 // 8 byte register but they are in the wrong part of the
414 // word so adjust loc to point at the right place.
415 nl = (narrowOop*)((address)nl + 4);
416 }
417 #endif
418 oop_fn->do_oop(nl);
419 }
420 }
421 }
422 }
754
755
756 void DerivedPointerTable::clear() {
757 // The first time, we create the list. Otherwise it should be
758 // empty. If not, then we have probably forgotton to call
759 // update_pointers after last GC/Scavenge.
760 assert (!_active, "should not be active");
761 assert(_list == NULL || _list->length() == 0, "table not empty");
762 if (_list == NULL) {
763 _list = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<DerivedPointerEntry*>(10, true); // Allocated on C heap
764 }
765 _active = true;
766 }
767
768
769 // Returns value of location as an int
770 intptr_t value_of_loc(oop *pointer) { return cast_from_oop<intptr_t>((*pointer)); }
771
772
773 void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) {
774 assert(GC::gc()->heap()->is_in_or_null(*base_loc), "not an oop");
775 assert(derived_loc != base_loc, "Base and derived in same location");
776 if (_active) {
777 assert(*derived_loc != (oop)base_loc, "location already added");
778 assert(_list != NULL, "list must exist");
779 intptr_t offset = value_of_loc(derived_loc) - value_of_loc(base_loc);
780 // This assert is invalid because derived pointers can be
781 // arbitrarily far away from their base.
782 // assert(offset >= -1000000, "wrong derived pointer info");
783
784 if (TraceDerivedPointers) {
785 tty->print_cr(
786 "Add derived pointer@" INTPTR_FORMAT
787 " - Derived: " INTPTR_FORMAT
788 " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: " INTX_FORMAT ")",
789 p2i(derived_loc), p2i((address)*derived_loc), p2i((address)*base_loc), p2i(base_loc), offset
790 );
791 }
792 // Set derived oop location to point to base.
793 *derived_loc = (oop)base_loc;
794 assert_lock_strong(DerivedPointerTableGC_lock);
795 DerivedPointerEntry *entry = new DerivedPointerEntry(derived_loc, offset);
796 _list->append(entry);
797 }
798 }
799
800
801 void DerivedPointerTable::update_pointers() {
802 assert(_list != NULL, "list must exist");
803 for(int i = 0; i < _list->length(); i++) {
804 DerivedPointerEntry* entry = _list->at(i);
805 oop* derived_loc = entry->location();
806 intptr_t offset = entry->offset();
807 // The derived oop was setup to point to location of base
808 oop base = **(oop**)derived_loc;
809 assert(GC::gc()->heap()->is_in_or_null(base), "must be an oop");
810
811 *derived_loc = (oop)(((address)base) + offset);
812 assert(value_of_loc(derived_loc) - value_of_loc(&base) == offset, "sanity check");
813
814 if (TraceDerivedPointers) {
815 tty->print_cr("Updating derived pointer@" INTPTR_FORMAT
816 " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: " INTX_FORMAT ")",
817 p2i(derived_loc), p2i((address)*derived_loc), p2i((address)base), offset);
818 }
819
820 // Delete entry
821 delete entry;
822 _list->at_put(i, NULL);
823 }
824 // Clear list, so it is ready for next traversal (this is an invariant)
825 if (TraceDerivedPointers && !_list->is_empty()) {
826 tty->print_cr("--------------------------");
827 }
828 _list->clear();
829 _active = false;
|