This section discusses how threads and synchronization can be optimized in an adaptive runtime environment.
As was mentioned when the different types of locks were introduced, one of the most important optimizations in an adaptive runtime is the ability to convert thin locks to fat locks and vice versa, depending on load and contention. Both the code generator and the lock implementation will attempt to solve this problem as efficiently as possible.
In an adaptive environment, the runtime has the benefit of free lock profiling information (at least a small amount of free lock profiling information, as, we shall see, doing complete in-depth lock profiling incurs some runtime overhead). Whenever a lock is taken or released, information can be logged about who is trying to get the lock and how many times it has been contended. So, if a single thread has failed to acquire a thin lock in too many subsequent attempts, it makes...