Skip to content

Commit

Permalink
8235305: Corrupted oops embedded in nmethods due to parallel modifica…
Browse files Browse the repository at this point in the history
…tion during optional evacuation

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.

Co-authored-by: Erik Osterlund <erik.osterlund@oracle.com>
Co-authored-by: Stefan Johansson <stefan.johansson@oracle.com>
Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com>
Reviewed-by: sjohanss, stefank
  • Loading branch information
4 people committed Jan 22, 2020
1 parent f7165c3 commit e3c7f43
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/hotspot/share/gc/g1/g1OopClosures.hpp
Expand Up @@ -152,7 +152,8 @@ class G1ParCopyHelper : public OopClosure {

enum G1Barrier {
G1BarrierNone,
G1BarrierCLD
G1BarrierCLD,
G1BarrierNoOptRoots // Do not collect optional roots.
};

enum G1Mark {
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/g1/g1OopClosures.inline.hpp
Expand Up @@ -246,7 +246,7 @@ void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) {
} else {
if (state.is_humongous()) {
_g1h->set_humongous_is_live(obj);
} else if (state.is_optional()) {
} else if ((barrier != G1BarrierNoOptRoots) && state.is_optional()) {
_par_scan_state->remember_root_into_optional_region(p);
}

Expand Down
11 changes: 10 additions & 1 deletion src/hotspot/share/gc/g1/g1SharedClosures.hpp
Expand Up @@ -40,13 +40,22 @@ class G1SharedClosures {
public:
G1ParCopyClosure<G1BarrierNone, Mark> _oops;
G1ParCopyClosure<G1BarrierCLD, Mark> _oops_in_cld;
// We do not need (and actually should not) collect oops from nmethods into the
// optional collection set as we already automatically collect the corresponding
// nmethods in the region's strong code roots set. So set G1BarrierNoOptRoots in
// this closure.
// If these were present there would be opportunity for multiple threads to try
// to change this oop* at the same time. Since embedded oops are not necessarily
// word-aligned, this could lead to word tearing during update and crashes.
G1ParCopyClosure<G1BarrierNoOptRoots, Mark> _oops_in_nmethod;

G1CLDScanClosure _clds;
G1CodeBlobClosure _codeblobs;

G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty) :
_oops(g1h, pss),
_oops_in_cld(g1h, pss),
_oops_in_nmethod(g1h, pss),
_clds(&_oops_in_cld, process_only_dirty),
_codeblobs(pss->worker_id(), &_oops, needs_strong_processing()) {}
_codeblobs(pss->worker_id(), &_oops_in_nmethod, needs_strong_processing()) {}
};

0 comments on commit e3c7f43

Please sign in to comment.