|Title||mps_definalize might not work|
|Assigned user||Gareth Rees|
|Description||The following sequence of events is possible:|
1. The client program calls mps_finalize(O) for an object O in a moving pool.
2. The MRG pool adds a reference to O to an MRGRefSeg.
3. A collection starts and the MRGRefSeg becomes grey and so gets a read barrier.
4. The object O gets moved to newspace.
5. The client program calls mps_definalize(O).
6. MRGDeregister iterates over the MRGRefSegs and compares O to each finalizable reference by calling MRGRefPartRef.
7. MRGRefPartRef can't afford to hit the read barrier and so gets the finalizable reference by calling ArenaPeek.
8. But the MRGRefSeg is grey and so ArenaPeek returns a reference to oldspace, which doesn't compare equal to O, and so MRGDeregister fails to find the reference and returns ResFAIL.
The same issue arises with respect to the calls to ArenaPeek in mps_finalize and mps_definalize themselves (if the reference to the object being (de)registered is itself stored in a moving pool). See mpsi.c.
|Analysis||We could emulate the read barrier hit (essentially implementing a software barrier) by calling ArenaRead instead of ArenaPeek inside MRGRefPartRef and mps_finalize and mps_definalize. (But these are in fact all the uses of ArenaPeek –- so a more robust solution would be to make ArenaPeek use the software barrier when peeking at a location owned by the arena.)|
DL suggests refactoring the finalization data structures to resolve job003953 (Definalization doesn't scale) and solving this at the same time. But wouldn't the same issue recur whatever data structure you used?
|Created by||Gareth Rees|
|Created on||2018-06-19 13:34:39|
|Last modified by||Gareth Rees|
|Last modified on||2018-07-05 16:29:24|
|History||2018-06-19 GDR Created.|
|194453||closed||2018-07-05 16:28:15||Gareth Rees||Merge branch/2018-06-18/mrgseg into the master sources.|