cosmos72 / stmx

High performance Transactional Memory for Common Lisp
http://stmx.org/
241 stars 14 forks source link

LispWorks specific: were slots change from tnon-transactional to transaction, the parents need (:optimize-slot-access nil) #18

Open Yehouda opened 4 years ago

Yehouda commented 4 years ago

The code already adds (:optimize-slot-access nil) to transactional classes, but when such a class is inherited from non-transactional class and overrides a slot to make it transactional, it needs to ensure that all accesses to this slot are not optimized.

For example, the class stmx.util:tmap overrides the slot root which is inherited from stmx.util:gmap via stmx.util:rbmap, and make it transactional. But when an object of class stmx.util:tmap is passed to the method stmx.util::gmap/rebalance-after-insert on stmx.util:rbmap, it may set the root slot, and this access is optimized, because it is on an instance stmx.util:rbmap, which allows optimizations. LispWorks optimizes slot-value and (setf slot-value) on the arguments of methods when the specializer class allows it (not documented properly). To prevent that, stmx.util:rbmap needs to have (:optimize-slot-access nil) too. In principle stmx.util:gmap needs it too, but there are no slot-value accesses to root in a method specilizes on stmx.util:gmap, so this does not causes problem.

To pass the tests, we (LispWorks ltd) also needed to add it to stmx.util:ghash-table. With these two fixes, all the tests in stmx.test work,but really all classes with slots that are overriden to transactional need to either have (:optimize-slot-access nil), or ensure that they don't use slot-value on any of these slots in any ofthe methods that specialize on them.

cosmos72 commented 4 years ago

Thanks for spotting this! As you can imagine, the code was tested very lightly on LispWorks.