company_banner

Владимир Иванов, Oracle — Глубокое погружение в invokedynamic

    Этот анонс посвящается тем, кто ныл всю зиму, что на JUG.ru давно не было хардкора.

    В среду, 11 марта, в петербургском офисе компании Oracle состоится встреча JUG.ru c Владимиром Ивановым, инженером команды HotSpot JVM.

    Тема встречи — инструкция invokedynamic и ее реализация в JDK/JVM.



    В Java 7 на уровне байткода появилась новая инструкция — invokedynamic. Инструкция с программируемым связыванием позволила динамическим языкам на Java платформе достичь новых высот производительности. JRuby активно использует invokedynamic начиная с Java 7, а в Java 8 появилась среда исполнения для JavaScript, полностью основанная на новом API.

    Основной акцент в докладе будет сделан на внутренней реализации java.lang.invoke API и поддержке новой инструкции в JVM. Особое внимание будет уделено взаимодействию JVM и Java-уровня реализации.

    Участие бесплатное, регистрация ТУТ.

    Владимир @iwan0www Иванов — ведущий инженер Oracle, работает в группе разработки виртуальной Java-машины HotSpot. Специализируется на JIT-компиляции и поддержке альтернативных языков на платформе Java. Владимир пришел в Sun Microsystems (приобретена Oracle в 2010) в 2005 году и с того момента поучаствовал в большом количестве проектов, связанных с Java (HotSpot JVM, RTSJ, JavaFX).

    Прошлые выступления Владимира на JUG.ru, Joker и JPoint можно найти тут.

    Вопросы к спикеру
    Если у вас есть какие-то вопросы к Владимиру по поводу invokedynamic или HotSpot JVM в целом — приходите на встречу: сможете услышать ответ из первых уст!

    Вопросы от тех, кто не сможет прийти, мы традиционно собираем в комментариях к данному топику.
    JUG.ru Group
    830,00
    Конференции для программистов и сочувствующих. 18+
    Поделиться публикацией

    Комментарии 14

      +1
      Завтра пойду попрошусь в Питер :-)
        0
        В командировку, как минимум!

        А так — дождитесь апрельской конференции JPoint, а на после уже окончательно переезжайте!
          0
          Не, переезжать не вариант. В Питере столько не платят :(
          А вот заехать на денек на доклад — да, самое то.
            0
            Зря вы так. Питер — это Питер. Мало кого оттуда выманишь «московской» зарплатой.
              0
              Я люблю Питер, но именно как «турист».
        0
        Интересует насколько этот доклад будет пересекаться с докладом «Invokedynamic: роскошь или необходимость?».
          0
          «Invokedynamic: роскошь или необходимость?» — короткий вариант, без погружения в кишки. Тут будет больше времени, Владимир успеет осветить гораздо больше моментов, чем на Джокере полтора года назад. Ну и времени много прошло, Java 8 вышла, Nashorn, все дела.
          +4
          Есть вопрос про JIT-компиляцию в HotSpot (1.8.0.31 у меня стоит), но не связанный с invokedynamic. Вчера экспериментировал с кодом, эмулирующим коллекцию на примитивном типе int. При этом хотелось, чтобы при обходе вида for(int val : collection) не происходило боксинга. Ну то есть я в итераторе коллекции делаю боксинг, а в конструкции for сразу происходит анбоксинг. Комбинацию боксинг-анбоксинг JIT-компилятор на раз выкашивает (например, new Integer(i).toString() и Integer.toString(i) JIT-компилируются в одинаковый код и по быстродействию эквивалентны). Инлайнить JIT-компилятор тоже неплохо умеет. Я даже создал специальный тип IntegerIterator implements Iterator<Integer> и метод iterator() коллекции объявил с ковариантным возвращаемым типом. И коллекция используется конкретного типа, а не какое-нибудь Iterable. А всё равно не инлайнит и как следствие итерация получается раз в 10 медленнее :( Что я не так делаю? Это из-за того, что в байткоде invokeinterface Iterator.next() и раз интерфейс, то JIT-компилятор умывает руки?
            +4
            Ещё немного поковырял код. Оказалось, что если возвращать из next() не Integer.valueOf(primitive), а new Integer(primitive), то вся цепочка легко заводится даже без дополнительных приседаний в виде ковариантных возвращаемых значений. Соотвественно вопрос снимается, но возникает другой: нельзя ли специально обрабатывать Integer.valueOf (и аналоги для других типов), чтобы при JIT-компиляции он работал не хуже, чем new Integer?

            Код моего бенчмарка здесь. Результат примерно такой:

            Benchmark                            Mode  Cnt   Score   Error  Units
            IteratorBench.testArray              avgt   30   3,555 ± 0,015  us/op // итерация по массиву — контроль
            IteratorBench.testIteratorList       avgt   30   8,784 ± 0,062  us/op // итерация по ArrayList<Integer> — контроль
            IteratorBench.testIntIterator        avgt   30   3,556 ± 0,022  us/op // свой класс итератора, явно возвращает примитив
            IteratorBench.testIterator           avgt   30  49,804 ± 0,615  us/op // итерация по коллекции Iterable<Integer> с автобоксингом в next()
            IteratorBench.testIteratorAbstract   avgt   30  52,482 ± 1,946  us/op // то же, но метод принимает а Iterable<Integer>
            IteratorBench.testIterator2          avgt   30   3,585 ± 0,039  us/op // итерация по коллекции Iterable<Integer> с new Integer() в next()
            IteratorBench.testIterator2Abstract  avgt   30   3,587 ± 0,036  us/op // то же, но метод принимает а Iterable<Integer>
            
              0
              скинул Вовину почту в личку — спрашивай там :)
                0
                Что означает «то же, но метод принимает а Iterable»?
                А по-существу — возможно переполняется максимальный размер инлайна на вызове Integer.valueOf(primitive) — вот, такое наивное предположение.
                Не пробовали поиграться с -XX:MaxInlineSize= (например, 70 там выставить) и -XX:InlineSmallCode= (тут подбирать нужно, но можно попробовать поставить 255 — должно точно хватить)?
                  +4
                  Коряво отредактировал, извините. Посмотрите код по ссылке. В одном случае метод, который обходил коллекцию, принимает в качестве параметра конкретный тип коллекции (например, IntCollection). Во втором случае метод принимает Iterable<Integer>, то есть снаружи его могут вызвать с любой коллекцией и решение об инлайнинге JIT-компилятору принять сложнее.

                  Отписался Владимиру, он говорит, что это похоже на баг и обещал разобраться.
                  0
                  А чем последний случай отличается от предпоследнего?

                  Ps идея очень красивая.
                    0
                    Если вы имеете в виду, чем отличается IteratorBench.testIterator2 и IteratorBench.testIterator2Abstract, то ответил выше.

                    Владимир подсказал, кстати, что с опциями -XX:+UnlockExperimentalVMOptions -XX:+AggressiveUnboxing производительность варианта с анбоксингом в несколько раз выше, хотя всё же не достигает производительности testIterator2. Возможно, со временем AggressiveUnboxing будет включено по умолчанию.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое