First-class methods in JVM 7
От: maxkar  
Дата: 20.04.13 07:50
Оценка:
Последнее время ковыряюсь с байткодом JVM (7-ка). В том числе с нововведениями вроде invokedynamic. И вот в КСВ прошла информация о том, что 8-ке он будет использоваться для генерации лямбд. Проблема в том, что invokedynamic очень хитрая инструкция и использовать ее для реализации first-class functions нецелесообразно. Поэтому я решил исследовать этот вопрос подробнее.

Исследование показало, что в JVM 7 уже есть аналог first-class function. Это MethodHandle. По сути, MethodHandle — это как раз полноценный метод, которому не хватило типизации в языке и рантайме. Мы не можем "уточнить" тип MethodHandle на уровне JVM (т.е. ни тип параметров, ни тип результата), но подобная информация есть в рантайме и вызов этого метода строго типизирован! При этом MethodHandles позволяет проводить first-class трансформации (композиция, фильтрация аргументов, varargs конверсия), сам MethodHandle умеет биндится (какое-то подобие карринга, детально не проверял). Более того, "first class" являются не только методы, но и аксессоры полей (something.x, something.x = ...) и создание объекта (new Something).

Пока остаются вопросы, насколько использование MethodHandle может быть оптимизировано рантаймом. Уже по спецификации языка (JVM и Java library) определяется специальная обработка этого типа, так что можно ожидать "достаточно эффективной" реализации этого безобразия в рантайме. Например, тот же биндинг функции к объекту может быть реализован с меньшим уровнем косвенности, чем через интерфейс-обертку.

Есть на данный момент и не слишком хорошая новость. Пока основным способом получения MethodHandle является Reflection-based API (см. MethodHandles, MethodHandles.Lookup). Поэтому нужно аккуратно инициализировать все требуемые методы и старт приложения будет не самым быстрым. И это при том, что в класс-файлах эти MethodHandle поддерживаются напрямую! Т.е. проблема даже не в рантайме, а в отсутствии компиляторов, которые могут генерировать правильный код!

Я в дальнейшем планирую посмотреть на производительность различных вариантов MethodHandle в рантайме и сравнить с реализацией. Но это будет еще не слишком скоро, так как сначала я хочу сделать удобный инструмент сборки класс-файлов. Что-то уже есть, но очень не хватает вывода stack map (нужный для любых переходов на 51-й версии class file). Ну и удобных утилит для генерации вызовов тоже. Так что у меня приоритеты пока на удобстве генерации байт-кода, и только потом на остальных экспериментах. Если кто-то захочет тестировать производительность раньше, могу сгенерировать нужный байткод (с константами для methodHandle/methodType).

Примеры (java-код с обертками и "чистый" аналог одного примера в байткоде) можно взять здесь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.