src/hotspot/share/compiler/oopMap.cpp
changeset 54916 7136c9ac56a7
parent 54807 33fe50b6d707
child 54960 e46fe26d7f77
equal deleted inserted replaced
54915:278600885731 54916:7136c9ac56a7
    36 #include "oops/compressedOops.hpp"
    36 #include "oops/compressedOops.hpp"
    37 #include "runtime/frame.inline.hpp"
    37 #include "runtime/frame.inline.hpp"
    38 #include "runtime/handles.inline.hpp"
    38 #include "runtime/handles.inline.hpp"
    39 #include "runtime/signature.hpp"
    39 #include "runtime/signature.hpp"
    40 #include "utilities/align.hpp"
    40 #include "utilities/align.hpp"
       
    41 #include "utilities/lockFreeStack.hpp"
    41 #ifdef COMPILER1
    42 #ifdef COMPILER1
    42 #include "c1/c1_Defs.hpp"
    43 #include "c1/c1_Defs.hpp"
    43 #endif
    44 #endif
    44 #ifdef COMPILER2
    45 #ifdef COMPILER2
    45 #include "opto/optoreg.hpp"
    46 #include "opto/optoreg.hpp"
   335       if (UseJVMCICompiler) {
   336       if (UseJVMCICompiler) {
   336         ShouldNotReachHere();
   337         ShouldNotReachHere();
   337       }
   338       }
   338 #endif
   339 #endif
   339 #endif // !TIERED
   340 #endif // !TIERED
   340       // Protect the operation on the derived pointers.  This
       
   341       // protects the addition of derived pointers to the shared
       
   342       // derived pointer table in DerivedPointerTable::add().
       
   343       MutexLocker x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
       
   344       do {
   341       do {
   345         omv = oms.current();
   342         omv = oms.current();
   346         oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
   343         oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
   347         guarantee(loc != NULL, "missing saved register");
   344         guarantee(loc != NULL, "missing saved register");
   348         oop *derived_loc = loc;
   345         oop *derived_loc = loc;
   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 
   824           p2i(derived_loc), p2i((address)*derived_loc), p2i((address)base), offset);
   833           p2i(derived_loc), p2i((address)*derived_loc), p2i((address)base), offset);
   825     }
   834     }
   826 
   835 
   827     // Delete entry
   836     // Delete entry
   828     delete entry;
   837     delete entry;
   829     _list->at_put(i, NULL);
   838   }
   830   }
   839   assert(Entry::_list->empty(), "invariant");
   831   // Clear list, so it is ready for next traversal (this is an invariant)
       
   832   if (TraceDerivedPointers && !_list->is_empty()) {
       
   833     tty->print_cr("--------------------------");
       
   834   }
       
   835   _list->clear();
       
   836   _active = false;
   840   _active = false;
   837 }
   841 }
   838 
   842 
   839 #endif // COMPILER2_OR_JVMCI
   843 #endif // COMPILER2_OR_JVMCI