Code review request: 6810698: G1: _expanded flag on sparse RSets not cleared correctly (XXXS)
From the CR blurb: Each sparse RSet has two tables: cur and next. At the beginning, both tables are the same (i.e., the two references _cur and _next point to the same table). When a sparse table needs to be expanded during a GC, the flag _expanded on the table is set, a new table is created (pointed to by _next) and the RSet is added to the expanded list. After the collection (in fact, at the beginning of the next collection), we iterate over the expanded list, we get rid of the _cur tables, and set _cur to point to _next (so the _next table basically replaces the _cur table). Unfortunately, at that time, the _expanded flag is not reset. So, if the sparse table is expanded again, it is not added to the expanded list (that operation is conditional on !_expanded, so that the table is not added twice during the same GC). As a result, some of the sparse tables are left in an inconsistent state, which causes some entries not to be scanned correctly during a GC. http://cr.openjdk.java.net/~tonyp/6810698/webrev.00/ (one line change!!!) Tony -- ---------------------------------------------------------------------- | Tony Printezis, Staff Engineer | Sun Microsystems Inc. | | | MS BUR02-311 | | e-mail: tony.printezis@sun.com | 35 Network Drive | | office: +1 781 442 0998 (x20998) | Burlington, MA01803-0902, USA | ---------------------------------------------------------------------- e-mail client: Thunderbird (Solaris)
Gee, Tony, you forgot to rip the bang aid? ;) igor On Thursday 26 February 2009 10:04:55 Tony Printezis wrote:
From the CR blurb:
Each sparse RSet has two tables: cur and next. At the beginning, both tables are the same (i.e., the two references _cur and _next point to the same table). When a sparse table needs to be expanded during a GC, the flag _expanded on the table is set, a new table is created (pointed to by _next) and the RSet is added to the expanded list. After the collection (in fact, at the beginning of the next collection), we iterate over the expanded list, we get rid of the _cur tables, and set _cur to point to _next (so the _next table basically replaces the _cur table). Unfortunately, at that time, the _expanded flag is not reset. So, if the sparse table is expanded again, it is not added to the expanded list (that operation is conditional on !_expanded, so that the table is not added twice during the same GC). As a result, some of the sparse tables are left in an inconsistent state, which causes some entries not to be scanned correctly during a GC.
http://cr.openjdk.java.net/~tonyp/6810698/webrev.00/
(one line change!!!)
Tony
New webrev here: http://cr.openjdk.java.net/~tonyp/6810698/webrev.01/ I also resolved a related small issue (and I changed the title of the CR to reflect that; I didn't think it was worth opening a second one): There is an additional issue with the sparse RSets. When we iterate over a sparse RSet, we actually use the _next table, instead of the _cur one. This creates a race between the _next table being expanded and the iteration. The whole point of having two tables is to have a stable one (_cur) and one that might be modified (_next) so that we can look at the stable one safely during a GC. Iterating over _next is plain wrong. This fix, along with the fix related to the _expanded check, seem to have resolved all the "missing rem set" issues related to sparse tables. Tony Tony Printezis wrote:
From the CR blurb:
Each sparse RSet has two tables: cur and next. At the beginning, both tables are the same (i.e., the two references _cur and _next point to the same table). When a sparse table needs to be expanded during a GC, the flag _expanded on the table is set, a new table is created (pointed to by _next) and the RSet is added to the expanded list. After the collection (in fact, at the beginning of the next collection), we iterate over the expanded list, we get rid of the _cur tables, and set _cur to point to _next (so the _next table basically replaces the _cur table). Unfortunately, at that time, the _expanded flag is not reset. So, if the sparse table is expanded again, it is not added to the expanded list (that operation is conditional on !_expanded, so that the table is not added twice during the same GC). As a result, some of the sparse tables are left in an inconsistent state, which causes some entries not to be scanned correctly during a GC.
http://cr.openjdk.java.net/~tonyp/6810698/webrev.00/
(one line change!!!)
Tony
-- --------------------------------------------------------------------- | Tony Printezis, Staff Engineer | Sun Microsystems Inc. | | | MS UBUR02-311 | | e-mail: tony.printezis@sun.com | 35 Network Drive | | office: +1 781 442 0998 (x20998) | Burlington, MA 01803-2756, USA | --------------------------------------------------------------------- e-mail client: Thunderbird (Linux)
participants (2)
-
Igor Veresov
-
Tony Printezis