743 |
740 |
744 //------------------------------DerivedPointerTable--------------------------- |
741 //------------------------------DerivedPointerTable--------------------------- |
745 |
742 |
746 #if COMPILER2_OR_JVMCI |
743 #if COMPILER2_OR_JVMCI |
747 |
744 |
748 class DerivedPointerEntry : public CHeapObj<mtCompiler> { |
745 class DerivedPointerTable::Entry : public CHeapObj<mtCompiler> { |
749 private: |
746 oop* _location; // Location of derived pointer, also pointing to base |
750 oop* _location; // Location of derived pointer (also pointing to the base) |
747 intptr_t _offset; // Offset from base pointer |
751 intptr_t _offset; // Offset from base pointer |
748 Entry* volatile _next; |
752 public: |
749 |
753 DerivedPointerEntry(oop* location, intptr_t offset) { _location = location; _offset = offset; } |
750 static Entry* volatile* next_ptr(Entry& entry) { return &entry._next; } |
754 oop* location() { return _location; } |
751 |
755 intptr_t offset() { return _offset; } |
752 public: |
|
753 Entry(oop* location, intptr_t offset) : |
|
754 _location(location), _offset(offset), _next(NULL) {} |
|
755 |
|
756 oop* location() const { return _location; } |
|
757 intptr_t offset() const { return _offset; } |
|
758 Entry* next() const { return _next; } |
|
759 |
|
760 typedef LockFreeStack<Entry, &next_ptr> List; |
|
761 static List* _list; |
756 }; |
762 }; |
757 |
763 |
758 |
764 DerivedPointerTable::Entry::List* DerivedPointerTable::Entry::_list = NULL; |
759 GrowableArray<DerivedPointerEntry*>* DerivedPointerTable::_list = NULL; |
|
760 bool DerivedPointerTable::_active = false; |
765 bool DerivedPointerTable::_active = false; |
761 |
766 |
|
767 bool DerivedPointerTable::is_empty() { |
|
768 return Entry::_list == NULL || Entry::_list->empty(); |
|
769 } |
762 |
770 |
763 void DerivedPointerTable::clear() { |
771 void DerivedPointerTable::clear() { |
764 // The first time, we create the list. Otherwise it should be |
772 // The first time, we create the list. Otherwise it should be |
765 // empty. If not, then we have probably forgotton to call |
773 // empty. If not, then we have probably forgotton to call |
766 // update_pointers after last GC/Scavenge. |
774 // update_pointers after last GC/Scavenge. |
767 assert (!_active, "should not be active"); |
775 assert (!_active, "should not be active"); |
768 assert(_list == NULL || _list->length() == 0, "table not empty"); |
776 assert(is_empty(), "table not empty"); |
769 if (_list == NULL) { |
777 if (Entry::_list == NULL) { |
770 _list = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<DerivedPointerEntry*>(10, true); // Allocated on C heap |
778 void* mem = NEW_C_HEAP_OBJ(Entry::List, mtCompiler); |
|
779 Entry::_list = ::new (mem) Entry::List(); |
771 } |
780 } |
772 _active = true; |
781 _active = true; |
773 } |
782 } |
774 |
783 |
775 |
|
776 // Returns value of location as an int |
784 // Returns value of location as an int |
777 intptr_t value_of_loc(oop *pointer) { return cast_from_oop<intptr_t>((*pointer)); } |
785 inline intptr_t value_of_loc(oop *pointer) { |
778 |
786 return cast_from_oop<intptr_t>((*pointer)); |
|
787 } |
779 |
788 |
780 void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) { |
789 void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) { |
781 assert(Universe::heap()->is_in_or_null(*base_loc), "not an oop"); |
790 assert(Universe::heap()->is_in_or_null(*base_loc), "not an oop"); |
782 assert(derived_loc != base_loc, "Base and derived in same location"); |
791 assert(derived_loc != base_loc, "Base and derived in same location"); |
783 if (_active) { |
792 if (_active) { |
784 assert(*derived_loc != (void*)base_loc, "location already added"); |
793 assert(*derived_loc != (void*)base_loc, "location already added"); |
785 assert(_list != NULL, "list must exist"); |
794 assert(Entry::_list != NULL, "list must exist"); |
786 intptr_t offset = value_of_loc(derived_loc) - value_of_loc(base_loc); |
795 intptr_t offset = value_of_loc(derived_loc) - value_of_loc(base_loc); |
787 // This assert is invalid because derived pointers can be |
796 // This assert is invalid because derived pointers can be |
788 // arbitrarily far away from their base. |
797 // arbitrarily far away from their base. |
789 // assert(offset >= -1000000, "wrong derived pointer info"); |
798 // assert(offset >= -1000000, "wrong derived pointer info"); |
790 |
799 |
796 p2i(derived_loc), p2i((address)*derived_loc), p2i((address)*base_loc), p2i(base_loc), offset |
805 p2i(derived_loc), p2i((address)*derived_loc), p2i((address)*base_loc), p2i(base_loc), offset |
797 ); |
806 ); |
798 } |
807 } |
799 // Set derived oop location to point to base. |
808 // Set derived oop location to point to base. |
800 *derived_loc = (oop)base_loc; |
809 *derived_loc = (oop)base_loc; |
801 assert_lock_strong(DerivedPointerTableGC_lock); |
810 Entry* entry = new Entry(derived_loc, offset); |
802 DerivedPointerEntry *entry = new DerivedPointerEntry(derived_loc, offset); |
811 Entry::_list->push(*entry); |
803 _list->append(entry); |
812 } |
804 } |
813 } |
805 } |
|
806 |
|
807 |
814 |
808 void DerivedPointerTable::update_pointers() { |
815 void DerivedPointerTable::update_pointers() { |
809 assert(_list != NULL, "list must exist"); |
816 assert(Entry::_list != NULL, "list must exist"); |
810 for(int i = 0; i < _list->length(); i++) { |
817 Entry* entries = Entry::_list->pop_all(); |
811 DerivedPointerEntry* entry = _list->at(i); |
818 while (entries != NULL) { |
|
819 Entry* entry = entries; |
|
820 entries = entry->next(); |
812 oop* derived_loc = entry->location(); |
821 oop* derived_loc = entry->location(); |
813 intptr_t offset = entry->offset(); |
822 intptr_t offset = entry->offset(); |
814 // The derived oop was setup to point to location of base |
823 // The derived oop was setup to point to location of base |
815 oop base = **(oop**)derived_loc; |
824 oop base = **(oop**)derived_loc; |
816 assert(Universe::heap()->is_in_or_null(base), "must be an oop"); |
825 assert(Universe::heap()->is_in_or_null(base), "must be an oop"); |
817 |
826 |
818 *derived_loc = (oop)(((address)base) + offset); |
827 *derived_loc = (oop)(((address)base) + offset); |
819 assert(value_of_loc(derived_loc) - value_of_loc(&base) == offset, "sanity check"); |
828 assert(value_of_loc(derived_loc) - value_of_loc(&base) == offset, "sanity check"); |
820 |
829 |