Здравствуйте, elw00d, Вы писали:
E>Спасибо, но вот как раз хотелось бы конкретики — я же пытаюсь разобраться на самом низком уровне как оно работает
Ну а что конкретика? Конкретика в
спеках. А если на пальцах, то это уже 100 раз объясняли: при первом прохождении через invokedynamic вызывается bootstrap-метод с параметрами, указанными в дескрипторе callsite-а. Этот метод генерит CallSite, этот CallSite где-то запоминается. Далее, вызывается что-то вроде callSite.getTarget().invokeExact(аргументы из дескриптора callsite-а). При всех последующих прохождениях через callsite первая часть (т.е. bootstrap) не вызывается. Да, чтобы не путаться: дескриптор InvokeDynamic
VM spec, 4.4.1 содержит описания двух методов: bootstrap и того, который потом вызывается в callsite'е.
E>Кстати, по докам вообще не очень понятно — что мы имеем на выходе этой инструкции. То ли она сама выполняет вызов метода, то ли она просто кладёт на вершину стека экземпляр какого-нибудь MethodHandle, и дальше надо его вызывать одним из «обычных» invoke-инструкций.
Всё сама. Про это чётко написано в спеках.
Кстати, немного оффтоп. Конечно, InvokeDynamic штука нужная, но напрочь убивает статический анализ (ну если только не привязываться к конкретным bootstrap-методам вроде LambdaMetafactory). Для случая с тем же LambdaMetafactory, могли бы предусмотреть другой механизм, для статических случаев, вроде тех же лямбд. А привязываться не всегда возможно — а ну как разработчики всяких Скал и Грувей понаизобретают своих LambdaMetafactory. И в Android InvokeDynamic не поддерживается. Да и вообще, какая-то макроинструкция, которая делает всё и сразу, понять и переварить её сложновато, а реализовать ещё сложнее. В общем, я так c осторожностью настроен к InvokeDynamic.