The JITs (C1, C2) must not bail out to the interpreter when they encounter an invokedynamic call site. Rather, they must load the target method from the CallSite and perform a MethodHandle.invoke call on it, and possibly also call the bootstrap method. The target method, if available at compile time, should be optimistically inlined, as if for a bimorphic call site. Bail-outs to the interpreter should be limited to deoptimizations, as with other dynamically typed call sites.
The structure of the target method handle should be reified to the compiler as a "synthetic method", a ciMethod or even a real methodOop. In this way the usual bytecode parser can be used to generate the IR for it. This design will also allow method handles to be shrink-wrapped when necessary, as (for example) in interface injection.