RFR: 8369048: GenShen: Defer ShenFreeSet::available() during rebuild [v2]

Kelvin Nilsen kdnilsen at openjdk.org
Wed Nov 12 00:58:45 UTC 2025


On Tue, 11 Nov 2025 22:04:04 GMT, Kelvin Nilsen <kdnilsen at openjdk.org> wrote:

>> As I write this, I realize that in the most general case where two threads may call these API's independently in a fastdebug build, you could theoretically get into a deadlock because they attempted to acquire locks in different orders (this possibility exists -- statically -- only in the fastdebug builds).
>> 
>> The general MuteLocker machinery has ranked mutexes to avoid such situations through static ranking and checks while acquiring locks (in debug builds as a way of potentially catching such situations and flagging them).
>> 
>> With such ranking though this code would assert because the locks are acquired in different order between here and elsewhere.
>> 
>> In product builds you are fine because the rebuild lock acts as a "leaf lock" (in hotspot parlance). But there seems to be a definite possibility of deadlock in debug builds if/when the rebuild is attempted by one thread while another checks available and attempts to acquire the heap lock to check the assertion. You could solve it by acquiring the heap lock before calling the work method where the assertion check is done.
>> 
>> However, I'd be much more comfortable if we used some form of lock rank framework, unless it was utterly impossible to do so for some reason. (Here it was easy to spot the lock order inversion because it was in the code. Of course, if a debug build deadlocked you would also figure out the same, but having lock ordering gives you a quick and easy way to verify if there's potential for trouble.)
>> 
>> Not sure of the history of ShenandoahLock or why the parallel infra to MutexLocker was introduced (perhaps for allowing some performance/tunability), but might be worthwhile to see if we want to build lock rank checks in for robustness/maintainability.
>
> I'm coming back to this PR after working on others.  Thanks for your comments.
> 
> This is a good catch.  I know better than to do that!  Sorry.
> 
> My intention was to rank-order the locks.  Whenever multiple locks are held, it should be in this order:
>   first acquire the global heap lock
>   In nested context, acquire the rebuild_lock
> 
> Any thread that only acquires the global heap lock or only acquires the rebuild_lock will not deadlock.
> 
> Multiple threads that acquire both locks will not deadlock because they acquire in the same order.
> 
> The code you identified was definitely a problem because we were acquiring the two lock in the wrong order.  I'm going to remove that assert and the lock associated with it.

I've updated this comment to clarify the refined intent.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27612#discussion_r2516294135


More information about the hotspot-gc-dev mailing list