The thing that jumps to mind for me is string interning - literals, anything in the constant pool and anything manually intern()
ed points to the same string object. If you start messing around with the contents of an interned string literal, you may well see the exact same alterations on all the other literals using the same underlying object.
I'm not sure whether the above actually happens since I've never tried (in theory it will, I don't know if something happens under the scene to stop it but I doubt it) but it's things like that that could throw up potential problems. Of course, it could also throw up problems at the Java level through just passing multiple references to the same string around and then using a reflection attack to alter the object from one of the references. Most people (me included!) won't explicitly guard against that sort of thing in code, so using that attack with any code that's not your own, or your own code if you haven't guarded against that either, could cause all sorts of bizarre, horrible bugs.
It's an interesting area theoretically, but the more you dig around the more you see why anything along these lines is a bad idea!
Speaking outside of string, there's no performance enhancements I know of for an object being immutable (indeed I don't think the JVM can even tell at the moment whether an object is immutable, reflection attacks aside.) It could throw things like the checker-framework off though or anything that tries to statically analyse the code to guarantee it's immutable.