uff, I started having doubts in my own understanding, thanks for being patient with me.
I agree that having hashCode mutate the object's state is weird. I had some thoughts about it – this particular mutation seems to be "safe" even from multi-threaded point of view. If another thread sees a stale value of wlen, then the only thing that is going to happen is it will scan more memory; for ands, ors and other types of operations this will have no effect. So assuming hashCode/equals is the ONLY method you're calling concurrently, it shouldn't break things. A similar kind of trickery goes on in String#hashCode (caching to a non-volatile field), although that object is immutable, so it's a slightly different scenario.
To be honest, my preference for this would be to either maintain the wlen field during all operations (like java.util.BitSet) or at least to clearly state (JavaDoc?) that trimTrailingZeros() should be invoked prior to publishing the object for other threads for increased performance (in case you fiddle with bits and clear the tail). In the second options, your patch does a fine job of not mutating the object and correcting the bug.
Thanks for an interesting discussion.