< prev index next >

src/hotspot/share/gc/g1/g1OopClosures.hpp

Print this page
rev 57716 : 8235305: Corrupted oops embedded in nmethods due to parallel modification during optional evacuation
Summary: During optional evacuation it is possible that G1 modifies oops embedded in nmethods in parallel. One source are oop* gathered by a previous evacuation phase in the optional roots, the other the region's strong code roots list. Since these oops may be unaligned on x64, this can result in them being corrupted. The fix is to not gather embedded oops in the optional roots list as the strong code roots list contains them already.
Contributed-by: erik.osterlund@oracle.com, stefan.johansson@oracle.com, stefan.karlsson@oracle.com, thomas.schatzl@oracle.com
Reviewed-by:


 135   ClassLoaderData* _scanned_cld;
 136   G1ConcurrentMark* _cm;
 137 
 138   // Mark the object if it's not already marked. This is used to mark
 139   // objects pointed to by roots that are guaranteed not to move
 140   // during the GC (i.e., non-CSet objects). It is MT-safe.
 141   inline void mark_object(oop obj);
 142 
 143   G1ParCopyHelper(G1CollectedHeap* g1h,  G1ParScanThreadState* par_scan_state);
 144   ~G1ParCopyHelper() { }
 145 
 146  public:
 147   void set_scanned_cld(ClassLoaderData* cld) { _scanned_cld = cld; }
 148   inline void do_cld_barrier(oop new_obj);
 149 
 150   inline void trim_queue_partially();
 151 };
 152 
 153 enum G1Barrier {
 154   G1BarrierNone,
 155   G1BarrierCLD

 156 };
 157 
 158 enum G1Mark {
 159   G1MarkNone,
 160   G1MarkFromRoot,
 161   G1MarkPromotedFromRoot
 162 };
 163 
 164 template <G1Barrier barrier, G1Mark do_mark_object>
 165 class G1ParCopyClosure : public G1ParCopyHelper {
 166 public:
 167   G1ParCopyClosure(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state) :
 168       G1ParCopyHelper(g1h, par_scan_state) { }
 169 
 170   template <class T> void do_oop_work(T* p);
 171   virtual void do_oop(oop* p)       { do_oop_work(p); }
 172   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 173 };
 174 
 175 class G1CLDScanClosure : public CLDClosure {




 135   ClassLoaderData* _scanned_cld;
 136   G1ConcurrentMark* _cm;
 137 
 138   // Mark the object if it's not already marked. This is used to mark
 139   // objects pointed to by roots that are guaranteed not to move
 140   // during the GC (i.e., non-CSet objects). It is MT-safe.
 141   inline void mark_object(oop obj);
 142 
 143   G1ParCopyHelper(G1CollectedHeap* g1h,  G1ParScanThreadState* par_scan_state);
 144   ~G1ParCopyHelper() { }
 145 
 146  public:
 147   void set_scanned_cld(ClassLoaderData* cld) { _scanned_cld = cld; }
 148   inline void do_cld_barrier(oop new_obj);
 149 
 150   inline void trim_queue_partially();
 151 };
 152 
 153 enum G1Barrier {
 154   G1BarrierNone,
 155   G1BarrierCLD,
 156   G1BarrierNoOptRoots  // Do not collect optional roots.
 157 };
 158 
 159 enum G1Mark {
 160   G1MarkNone,
 161   G1MarkFromRoot,
 162   G1MarkPromotedFromRoot
 163 };
 164 
 165 template <G1Barrier barrier, G1Mark do_mark_object>
 166 class G1ParCopyClosure : public G1ParCopyHelper {
 167 public:
 168   G1ParCopyClosure(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state) :
 169       G1ParCopyHelper(g1h, par_scan_state) { }
 170 
 171   template <class T> void do_oop_work(T* p);
 172   virtual void do_oop(oop* p)       { do_oop_work(p); }
 173   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 174 };
 175 
 176 class G1CLDScanClosure : public CLDClosure {


< prev index next >