I don't think it's the fault of the VM. There have been other languages that worked with intermediate code, and they weren't inefficient. It's just that fixing old stuff after you get millions of users leaves you with a very strange language, even a stranger one than if you add completely new stuff along the way. The latter is inevitable, but the former ought to be avoided. The Java people probably didn't realize in the beginning what they were building. (Well, of course, who would have, in their place?)