This is an alternative to #4283, which caches computed hashes inside CTransaction and CBlock.
It should cover more cases, but relies on the assumption that the hash does not change once computed (except for a few cases, where MarkDirty() is called), and that there are no two threads asking for a hash simultaneously for the same time (or otherwise don't destructively overwrite each other's data).
I also don't think these actually belong inside core data structures, but should be part of a "validation context" object for blocks or transactions instead. Those don't exist, however, and this simplifies the code in many places (by not requiring the hash to be passed separately to avoid recalculation).