Move conditionals about freezing closer to the definition of `freeze`

Reduces the number of places that care about the internals of how we
store and type cast attributes. We do not need to go through the
dup/freeze dance, as you couldn't have saved a frozen new record anyway,
and that is the only time we would end up modifying the frozen hash.
Merge pull request #15565 from sgrif/sg-no-unfreezing

Move conditionals about freezing closer to the definition of `freeze`