Wasn’t there already like instrumentation api that was run via premain?

That is an even lower level API that lets you manipulate the bytecode as a byte array. You still need to parse it to do anything useful, hence libraries like ASM. And if you want to compile more code at runtime (or generate bytecode), you'll need some way to do that.