< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp

Print this page
rev 59304 : 8245124: Shenandoah: optimize code root evacuation/update during concurrent class unloading


  93   if (oops.length() != _oops_count) {
  94     if (_oops != NULL) {
  95       FREE_C_HEAP_ARRAY(oop*, _oops);
  96       _oops = NULL;
  97     }
  98 
  99     _oops_count = oops.length();
 100     if (_oops_count > 0) {
 101       _oops = NEW_C_HEAP_ARRAY(oop*, _oops_count, mtGC);
 102     }
 103   }
 104 
 105   for (int index = 0; index < _oops_count; index ++) {
 106     _oops[index] = oops.at(index);
 107   }
 108   _has_non_immed_oops = non_immediate_oops;
 109 
 110   assert_same_oops();
 111 }
 112 
 113 void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) {
 114   for (int c = 0; c < _oops_count; c ++) {
 115     oops->do_oop(_oops[c]);
 116   }
 117 
 118   oop* const begin = _nm->oops_begin();
 119   oop* const end = _nm->oops_end();
 120   for (oop* p = begin; p < end; p++) {
 121     if (*p != Universe::non_oop_word()) {
 122       oops->do_oop(p);
 123     }
 124   }
 125 
 126   if (fix_relocations && _has_non_immed_oops) {
 127     _nm->fix_oop_relocations();
 128   }
 129 }
 130 
 131 void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& has_non_immed_oops) {
 132   has_non_immed_oops = false;
 133   // Find all oops relocations
 134   RelocIterator iter(nm);
 135   while (iter.next()) {
 136     if (iter.type() != relocInfo::oop_type) {
 137       // Not an oop
 138       continue;
 139     }
 140 
 141     oop_Relocation* r = iter.oop_reloc();
 142     if (!r->oop_is_immediate()) {
 143       // Non-immediate oop found
 144       has_non_immed_oops = true;
 145       continue;
 146     }
 147 
 148     oop value = r->oop_value();
 149     if (value != NULL) {
 150       oop* addr = r->oop_addr();


 198     ShouldNotReachHere();
 199   }
 200 };
 201 
 202 void ShenandoahNMethod::heal_nmethod(nmethod* nm) {
 203   ShenandoahNMethod* data = gc_data(nm);
 204   assert(data != NULL, "Sanity");
 205   assert(data->lock()->owned_by_self(), "Must hold the lock");
 206 
 207   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 208   if (heap->is_concurrent_mark_in_progress()) {
 209     if (heap->has_forwarded_objects()) {
 210       ShenandoahKeepNMethodMetadataAliveClosure<true> cl;
 211       data->oops_do(&cl);
 212     } else {
 213       ShenandoahKeepNMethodMetadataAliveClosure<false> cl;
 214       data->oops_do(&cl);
 215     }
 216   } else if (heap->is_concurrent_weak_root_in_progress()) {
 217     ShenandoahEvacOOMScope evac_scope;
 218     ShenandoahEvacuateUpdateRootsClosure<> cl;
 219     data->oops_do(&cl, true /*fix relocation*/);
 220   } else {
 221     // There is possibility that GC is cancelled when it arrives final mark.
 222     // In this case, concurrent root phase is skipped and degenerated GC should be
 223     // followed, where nmethods are disarmed.
 224     assert(heap->cancelled_gc(), "What else?");
 225   }
 226 }
 227 
 228 #ifdef ASSERT
 229 void ShenandoahNMethod::assert_alive_and_correct() {
 230   assert(_nm->is_alive(), "only alive nmethods here");
 231   ShenandoahHeap* heap = ShenandoahHeap::heap();
 232   for (int c = 0; c < _oops_count; c++) {
 233     oop *loc = _oops[c];
 234     assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
 235     oop o = RawAccess<>::oop_load(loc);
 236     shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress());
 237   }
 238 
 239   oop* const begin = _nm->oops_begin();




  93   if (oops.length() != _oops_count) {
  94     if (_oops != NULL) {
  95       FREE_C_HEAP_ARRAY(oop*, _oops);
  96       _oops = NULL;
  97     }
  98 
  99     _oops_count = oops.length();
 100     if (_oops_count > 0) {
 101       _oops = NEW_C_HEAP_ARRAY(oop*, _oops_count, mtGC);
 102     }
 103   }
 104 
 105   for (int index = 0; index < _oops_count; index ++) {
 106     _oops[index] = oops.at(index);
 107   }
 108   _has_non_immed_oops = non_immediate_oops;
 109 
 110   assert_same_oops();
 111 }
 112 


















 113 void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& has_non_immed_oops) {
 114   has_non_immed_oops = false;
 115   // Find all oops relocations
 116   RelocIterator iter(nm);
 117   while (iter.next()) {
 118     if (iter.type() != relocInfo::oop_type) {
 119       // Not an oop
 120       continue;
 121     }
 122 
 123     oop_Relocation* r = iter.oop_reloc();
 124     if (!r->oop_is_immediate()) {
 125       // Non-immediate oop found
 126       has_non_immed_oops = true;
 127       continue;
 128     }
 129 
 130     oop value = r->oop_value();
 131     if (value != NULL) {
 132       oop* addr = r->oop_addr();


 180     ShouldNotReachHere();
 181   }
 182 };
 183 
 184 void ShenandoahNMethod::heal_nmethod(nmethod* nm) {
 185   ShenandoahNMethod* data = gc_data(nm);
 186   assert(data != NULL, "Sanity");
 187   assert(data->lock()->owned_by_self(), "Must hold the lock");
 188 
 189   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 190   if (heap->is_concurrent_mark_in_progress()) {
 191     if (heap->has_forwarded_objects()) {
 192       ShenandoahKeepNMethodMetadataAliveClosure<true> cl;
 193       data->oops_do(&cl);
 194     } else {
 195       ShenandoahKeepNMethodMetadataAliveClosure<false> cl;
 196       data->oops_do(&cl);
 197     }
 198   } else if (heap->is_concurrent_weak_root_in_progress()) {
 199     ShenandoahEvacOOMScope evac_scope;
 200     heal_nmethod_metadata(data);

 201   } else {
 202     // There is possibility that GC is cancelled when it arrives final mark.
 203     // In this case, concurrent root phase is skipped and degenerated GC should be
 204     // followed, where nmethods are disarmed.
 205     assert(heap->cancelled_gc(), "What else?");
 206   }
 207 }
 208 
 209 #ifdef ASSERT
 210 void ShenandoahNMethod::assert_alive_and_correct() {
 211   assert(_nm->is_alive(), "only alive nmethods here");
 212   ShenandoahHeap* heap = ShenandoahHeap::heap();
 213   for (int c = 0; c < _oops_count; c++) {
 214     oop *loc = _oops[c];
 215     assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
 216     oop o = RawAccess<>::oop_load(loc);
 217     shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress());
 218   }
 219 
 220   oop* const begin = _nm->oops_begin();


< prev index next >