Есть ли оптимизатор байт-кода Java, который удаляет ненужные gotos? - PullRequest
18 голосов
/ 03 июня 2009

Проблема: у меня есть метод, который компилирует более 8000 байт байт-кода Java. HotSpot имеет магический лимит, который запрещает использование JIT для методов, длина которых превышает 8000 байт. (Да, разумно иметь огромный метод. Это цикл токенизатора.) Метод находится в библиотеке, и я не хочу требовать, чтобы пользователи библиотеки настраивали HotSpot для деактивации магического ограничения.

Наблюдение: декомпиляция байт-кода показывает, что Eclipse Java Compiler генерирует много бессмысленных переходов. (javac еще хуже.) То есть есть gotos, которые достижимы только с прыжков. Очевидно, что прыжок, который прыгает на гото, должен вместо этого прыгать прямо туда, где гото прыгает, и гото следует устранить.

Вопрос: существует ли оптимизатор байт-кода для файлов классов Java 5, который выравнивает бессмысленные цепочки переходов, а затем удаляет ненужные переходы?

Редактировать: я имею в виду такие узоры, как:

8698:   goto    8548
8701:   goto    0

Очевидно, что до второго гото можно добраться только путем прыжка до 8701, который также может быть прямым прыжком до 0.

Во втором исследовании эта сомнительная картина встречается чаще:

4257:   if_icmpne   4263
4260:   goto    8704
4263:   aload_0

Там, где, очевидно, хотелось бы, чтобы компилятор изменил сравнение «не равное» на сравнение «равное», перейти на 8704 и исключить переход.

Ответы [ 7 ]

1 голос
/ 03 июня 2009

Я чувствую твою боль. Я должен был написать парсер, который имел около 5kloc кода if (str.equals (...)). Я разбил несколько методов по принципу parse1, parse2 и т. Д. Если parse1 не привел к анализу ответа, был вызван parse2 и т. Д. Это не обязательно лучшие практики, но он делает то, что вам нужно .

0 голосов
/ 30 июня 2009

Список библиотек байт-кодов упоминает BCEL и ASM , о которых я слышал ранее, наряду со многими другими, делающими различные вещи.

0 голосов
/ 30 июня 2009

Повышается ли ваша производительность, если вы запускаете в своем классе средство сжатия / запутывания байт-кода? например, югард, гвардеец, ...

возможно, вы можете написать постпроцессор файла класса, используя asm, потому что ваш вариант использования очень специфичен.

даже если вы удалите все бессмысленные готы, это приведет вас к магическому пределу?

0 голосов
/ 03 июня 2009

Если это цикл токенизатора, было бы лучше сделать это с набором отображений, управляемых данными, и немного отражения в зависимости от ситуации?

Таким образом, вы должны хранить свои соответствия токенов в структуре, которая отображает их на данные о синтаксисе этого токена и методах, реализующих связанные функции. Lookup можно оптимизировать по структуре, и вы избежите большого цикла.

Это ставит вопрос о синхронизации данных и реализации, но вы можете генерировать данные из своей кодовой базы с помощью доклета или, возможно, аннотации.

Не зная точно, что делает ваш большой метод, мы ограничиваемся попытками оптимизировать его так, как вы считаете лучшим (а это, по-видимому, невозможно в любом случае).

0 голосов
/ 03 июня 2009

Было бы невозможно реорганизовать метод в подметоды? В любом случае современные JIT встраивают эти звонки.

0 голосов
/ 03 июня 2009

Имеет ли значение, если вы не компилируете с символами отладки (то есть флаг -g в javac)? Это может привести к тому, что метод опустится ниже магического предела.

0 голосов
/ 03 июня 2009

Один метод компилируется до 8000 байт? Кто-нибудь понимает этот код? Это проверяемое? Попробуйте разделить его на несколько (приватных?) Методов со значимыми именами, а не суетиться с оптимизатором!

ОК, может быть, есть случаи, допустимые крупными методами. Но извините, в вопросе нет подсказок.

...