When G1 experiences an evacuation failure objects for which we can't allocate space are forwarded to themselves. If an object has a non-standard header (e.g. it was locked or its hash value has been calculated), the object and its header value are recorded (in lock-step) in to a data structure (currently a growable array). After all the objects have been copied and scanned, the data structure where we have recorded the headers is walked and the displaced object headers are restored.
Currently the data structure in which we hold the displaced headers and the objects to which they belong is a global data structure (shared among the GC threads) and the restoration of the object headers is single-threaded.
The worst case latency (i.e. handling an evacuation failure) should be improved if the restoration of the displaced object headers was wrapped into a task that could be executed in parallel by the GC workers.