United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 7121623 G1: always be able to reliably calculate the length of a forwarded chunked array
7121623 : G1: always be able to reliably calculate the length of a forwarded chunked array

Details
Type:
Enhancement
Submit Date:
2011-12-14
Status:
Closed
Updated Date:
2012-03-29
Project Name:
JDK
Resolved Date:
2012-03-29
Component:
hotspot
OS:
generic
Sub-Component:
gc
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
hs23
Fixed Versions:
hs23

Related Reports
Backport:
Backport:
Relates:

Sub Tasks

Description
For the implementation of another CR (6484965: G1: piggy-back liveness accounting phase on marking) we need to be able to calculate the size of an object whose to-space image we mark during a GC. This is currently quite tricky given that if the object is already forwarded by another worker we cannot guarantee that the to-space image of said object is consistent (the other worker might still be in the process of copying the object, so when we try to read its to-image header we might get back junk).

One idea round this is to read the size from the object's from-image. This works most of the time apart from the case of chunked object arrays. For those we use the from-image length field to store the sarting index of the next chunk to process (and restore the real length when after we claim the last chunk). But, when we read such an array, we cannot be sure whether the length is the actual length or the next index.

The solution propose here to deal with the case of chunk object arrays is to always encode the index so that it is always negative before we store it in the from-image length field. We can easily do this with the following: -(index + 1) (+1 so that 0 is also encoded as a negative value). This way we can distinguish whether the length is really a valid length (>=0) or an encoded index (<0). In the latter case, and by being careful to only store the encoded index after we finish copying the object, we can simply read the correct length from the to-image of the object.
It turns out that the idea of using a negative value to encode the next index (in the length field of the from-image) does not work as it introduces a subtle race (see the Evaluation section for the details).

The alternative we'll try is to use the length field of the to-image (instead of the from-image) to keep track of the next index. This way, the from-image will always be consistent and we'll always be able to read the correct size from it.

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/02838862dec8
                                     
2012-03-22
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-rt/hotspot/rev/02838862dec8
                                     
2012-01-18
PUBLIC COMMENTS

Given that the proposed solution (described in the Description field) had a race (described in the Evaluation) field I ended up implementing an alternative which is to encode the next in index as before (i.e., the actual value of the next index) but store it in the to-space object, not the from-space object. This way, we can always reliably read the size of an object that is forwarded during a GC by reading it from the from-space.
                                     
2012-01-09
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-gc/hotspot/rev/02838862dec8
                                     
2012-01-07
EVALUATION

It turns out that the original proposal (use a negative length to encode the next index) has a subtle race. Below are the details from an e-mail I sent out.

Let's assume two threads, A and B, are racing to forward the same object array X. Consider the following interleaving:

Thread A:
is X forwarded? no

Thread B:
is X forwarded? no
size = X.size();
X' = allocate size
try to forward X to X'? yes
copy X to X'
chunk X, X.length is negative

Thread A:
size = X.size(); -> BOOM, as size() just read a negative length

Interesting this race exists today but it's benign due to either careful design or sheer luck. When A reads size = X.size() it will actually get a smaller size than the actual size of X and will allocate a chunk smaller than X (!!!). However, given that X is already forwarded it won't need to copy it and will undo the allocation. So, no harm done.
                                     
2011-12-27
EVALUATION

See Description.
                                     
2011-12-14
PUBLIC COMMENTS

I should add: I'd like to fix and push this separately as it's self-contained and I'd like to get it tested separately.
                                     
2011-12-14



Hardware and Software, Engineered to Work Together