mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
7014261: G1: RSet-related failures
A race between the concurrent cleanup thread and the VM thread while it is processing the "expanded sparse table list" causes both threads to try to free the same sparse table entry and either causes one of the threads to fail or leaves the entry in an inconsistent state. The solution is purge all entries on the expanded list that correspond go regions that are being cleaned up. Reviewed-by: brutisso, johnc
This commit is contained in:
parent
14f4450d25
commit
ded092cb70
7 changed files with 171 additions and 36 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -415,6 +415,38 @@ SparsePRT* SparsePRT::get_from_expanded_list() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void SparsePRT::reset_for_cleanup_tasks() {
|
||||
_head_expanded_list = NULL;
|
||||
}
|
||||
|
||||
void SparsePRT::do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task) {
|
||||
if (should_be_on_expanded_list()) {
|
||||
sprt_cleanup_task->add(this);
|
||||
}
|
||||
}
|
||||
|
||||
void SparsePRT::finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task) {
|
||||
assert(ParGCRareEvent_lock->owned_by_self(), "pre-condition");
|
||||
SparsePRT* head = sprt_cleanup_task->head();
|
||||
SparsePRT* tail = sprt_cleanup_task->tail();
|
||||
if (head != NULL) {
|
||||
assert(tail != NULL, "if head is not NULL, so should tail");
|
||||
|
||||
tail->set_next_expanded(_head_expanded_list);
|
||||
_head_expanded_list = head;
|
||||
} else {
|
||||
assert(tail == NULL, "if head is NULL, so should tail");
|
||||
}
|
||||
}
|
||||
|
||||
bool SparsePRT::should_be_on_expanded_list() {
|
||||
if (_expanded) {
|
||||
assert(_cur != _next, "if _expanded is true, cur should be != _next");
|
||||
} else {
|
||||
assert(_cur == _next, "if _expanded is false, cur should be == _next");
|
||||
}
|
||||
return expanded();
|
||||
}
|
||||
|
||||
void SparsePRT::cleanup_all() {
|
||||
// First clean up all expanded tables so they agree on next and cur.
|
||||
|
@ -484,6 +516,7 @@ void SparsePRT::clear() {
|
|||
_cur->clear();
|
||||
}
|
||||
_next = _cur;
|
||||
_expanded = false;
|
||||
}
|
||||
|
||||
void SparsePRT::cleanup() {
|
||||
|
@ -518,3 +551,15 @@ void SparsePRT::expand() {
|
|||
}
|
||||
add_to_expanded_list(this);
|
||||
}
|
||||
|
||||
void SparsePRTCleanupTask::add(SparsePRT* sprt) {
|
||||
assert(sprt->should_be_on_expanded_list(), "pre-condition");
|
||||
|
||||
sprt->set_next_expanded(NULL);
|
||||
if (_tail != NULL) {
|
||||
_tail->set_next_expanded(sprt);
|
||||
} else {
|
||||
_head = sprt;
|
||||
}
|
||||
_tail = sprt;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue