Комментарии 17
Какую версию Java-байткода вы поддерживаете? Java-6?
Как я понимаю, производительность вас сильно не волнует, если вы совсем от примитивных типов отказались?
Не очень понял, как транслируется вызов статического метода (invokestatic). Какой объект используется в качестве this?
Интерфейсы у вас есть в языке? Такие же, как в Java? Как у них устроена таблица виртуальных методов?
Как я понимаю, производительность вас сильно не волнует, если вы совсем от примитивных типов отказались?
Не очень понял, как транслируется вызов статического метода (invokestatic). Какой объект используется в качестве this?
Интерфейсы у вас есть в языке? Такие же, как в Java? Как у них устроена таблица виртуальных методов?
+2
4*спасибо за вопрос. :)
Чёткой отсылки к номеру версии байткода в документации soot я не нашёл, но последний билд проекта — от 2012 года, что наводит на мысль, что явно не 8. Скорее 6, да.
Производительности я считаю правильным достигать через JIT, сохраняя регулярную структуру формальной виртуальной машины. Внутри кода JIT ничто не мешает пускаться во все тяжкие, уходя от навязанных виртуальной машиной представлений. Собственно, даже в интерпретаторе любая формула из группы интегральных переменных будет отработана в бинарном виде, преобразование инта в объектную форму происходит только при вызовах и сохранениях переменных.
Вызов статики пока не реализован, но проблем тут нет вообще. Есть два простых варианта. первый — генерировать для статики специальный класс, второй — тупо делать статические методы так же как обычные, держать для них синглтон инстанс this, и при кодогенерации запрещать доступ к полям this. Спасибо ещё раз за вопрос, заодно я, кажется, определился с реализацией. :)
Интерфейсы запроектированы. Реализация реально не дошла. Есть два варианта реализации. Первый. Предпочтительный. Реально все пойнтера виртуальной машины таскают с собой пойнтер на интерфейс, по которому и происходит обращение к vmt. Это позволит реализовать cast с заменой в пойнтере интерфейса на любой нужный. Дальше вызов по vmt[ordinal интерфейса]. Второй вариант совсем тупой — invokedynamic. Но он пока без полиморфизма. Что, впрочем, тоже решается легко — передавать сигнатуру вместо имени метода.
Чёткой отсылки к номеру версии байткода в документации soot я не нашёл, но последний билд проекта — от 2012 года, что наводит на мысль, что явно не 8. Скорее 6, да.
Производительности я считаю правильным достигать через JIT, сохраняя регулярную структуру формальной виртуальной машины. Внутри кода JIT ничто не мешает пускаться во все тяжкие, уходя от навязанных виртуальной машиной представлений. Собственно, даже в интерпретаторе любая формула из группы интегральных переменных будет отработана в бинарном виде, преобразование инта в объектную форму происходит только при вызовах и сохранениях переменных.
Вызов статики пока не реализован, но проблем тут нет вообще. Есть два простых варианта. первый — генерировать для статики специальный класс, второй — тупо делать статические методы так же как обычные, держать для них синглтон инстанс this, и при кодогенерации запрещать доступ к полям this. Спасибо ещё раз за вопрос, заодно я, кажется, определился с реализацией. :)
Интерфейсы запроектированы. Реализация реально не дошла. Есть два варианта реализации. Первый. Предпочтительный. Реально все пойнтера виртуальной машины таскают с собой пойнтер на интерфейс, по которому и происходит обращение к vmt. Это позволит реализовать cast с заменой в пойнтере интерфейса на любой нужный. Дальше вызов по vmt[ordinal интерфейса]. Второй вариант совсем тупой — invokedynamic. Но он пока без полиморфизма. Что, впрочем, тоже решается легко — передавать сигнатуру вместо имени метода.
+1
>> Надо сказать, что эти виртуальные машины изрядно, хотя и совершенно случайно, похожи.
…
>> Как эта часть устроена в JVM, я не знаю до сих пор
Гм…
>> К примеру, локально, в точке вызова, совершенно невозможно выяснить, объектный это вызов (первый параметр — this), или нет.
А в чём проблема?
В байткоде это всегда invokestatic, а метод и так знает, что он статический.
>> Чёткой отсылки к номеру версии байткода в документации soot я не нашёл, но последний билд проекта — от 2012 года
Currently, Soot can process code from the following sources:
— Java (bytecode and source code up to Java 7), including other languages that compile to Java bytecode, e.g. Scala
…
© http://sable.github.io/soot/#what-input-formats-does-soot-provide
Последний коммит — две недели назад: https://github.com/Sable/soot/graphs/commit-activity
…
>> Как эта часть устроена в JVM, я не знаю до сих пор
Гм…
>> К примеру, локально, в точке вызова, совершенно невозможно выяснить, объектный это вызов (первый параметр — this), или нет.
А в чём проблема?
В байткоде это всегда invokestatic, а метод и так знает, что он статический.
>> Чёткой отсылки к номеру версии байткода в документации soot я не нашёл, но последний билд проекта — от 2012 года
Currently, Soot can process code from the following sources:
— Java (bytecode and source code up to Java 7), including other languages that compile to Java bytecode, e.g. Scala
…
© http://sable.github.io/soot/#what-input-formats-does-soot-provide
Последний коммит — две недели назад: https://github.com/Sable/soot/graphs/commit-activity
+2
Рад, что вы решили написать статью на Хабре. Приятно иметь возможность пообщаться с таким интересным человеком, так сказать, воочию.
Теперь по делу. Не считаете ли вы, что персистентную ОС с единым адресным пространством сегодня стоило бы разрабатывать без ВМ, а на основе ЯП с гарантиями защиты памяти типа Rust?
Теперь по делу. Не считаете ли вы, что персистентную ОС с единым адресным пространством сегодня стоило бы разрабатывать без ВМ, а на основе ЯП с гарантиями защиты памяти типа Rust?
+1
Спасибо на добром слове.
Ограничивать ОС одним ЯП, да ещё и не самым популярным — затея спорная. Да и гарантии защиты памяти даёт не сам язык, а среда исполнения+генератор кода. В Фантоме виртуальная машина самодостаточна с точки зрения обеспечения надёжности, но это же всё равно промежуточный этап — дальше будет генерация бинарного кода из байткода (JIT), и ВМ как таковая исчезнет, останется только в виде промежуточного представления программы.
Ограничивать ОС одним ЯП, да ещё и не самым популярным — затея спорная. Да и гарантии защиты памяти даёт не сам язык, а среда исполнения+генератор кода. В Фантоме виртуальная машина самодостаточна с точки зрения обеспечения надёжности, но это же всё равно промежуточный этап — дальше будет генерация бинарного кода из байткода (JIT), и ВМ как таковая исчезнет, останется только в виде промежуточного представления программы.
0
Да, ограничиваться одним языком не стоит, тут вы правы. Просто смущает мысль о необходимости раздутой среды исполнения, похожей на JVM. Дело в том, что разработчики Rust продемонстрировали, что можно почти полностью отказаться от среды исполнения (как в C), но обеспечить безопасность памяти и параллелизма на основе статического анализа (при наличии соотв. системы типов, разумеется). Потому тут напрашивается какое-то подмножество LLVM-IR, над которым тоже можно было бы проводить подобные проверки. Т.е., по-сути, это та же ВМ, но с минимальной средой исполнения (только проверки границ массива, стека, ещё что-то, без чего нельзя обойтись).
+1
Оно и в Яве давно так, интерпретатор почти уже не используется. Можно её вообще скомпилировать в бинарник (gcj, part of gcc compilers collection). Как таковая среда — это библиотека. Если она не нужна, можно получить сишный размер программы.
0
К сожалению, GCJ мертв. Из AOT компиляции для java байткода знаю только Excelsior JET
0
НЛО прилетело и опубликовало эту надпись здесь
А какой именно поддержки?
0
Не все так тривиально. Например, за invokedynamic там целая вселенная в runtime чтобы было производительно. Плюс есть всякие intrisics:http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/classfile/vmSymbols.hpp#l581
Вообще, не совсем понятно зачем такое делать в практическом смысле? JVM имеет много уровней оптимизации в compile/runtime. И последние добавляемые в язык/байткод фичи тесно завязаны на runtime. Если ваш runtime отличается существенно, то и производительности не видать.
Далее, что насчет jmm? Java это прежде всего спецификация. Если вы хотите поддерживать java программы, нужно будет гарантировать и совместимость. А там есть очень нетривиальные вещи. Та же java memory model.
Не говорю, что это вам не по силам, но действительно ли это цель?
Вообще, не совсем понятно зачем такое делать в практическом смысле? JVM имеет много уровней оптимизации в compile/runtime. И последние добавляемые в язык/байткод фичи тесно завязаны на runtime. Если ваш runtime отличается существенно, то и производительности не видать.
Далее, что насчет jmm? Java это прежде всего спецификация. Если вы хотите поддерживать java программы, нужно будет гарантировать и совместимость. А там есть очень нетривиальные вещи. Та же java memory model.
Не говорю, что это вам не по силам, но действительно ли это цель?
0
Задачей, очевидно, является не написание VM, а создание ОС с персистентной ортогональностью и виртуальной машиной в глобальной памяти. (Блекджеком и шахматами и поэтессами повеяло, да?)
С обычной явской VM я этот вес не подниму точно. С таким подходом — поднял до уровня proof of concept. То есть — пока оно себя оправдывает. Мне, кроме всего, важно понять ограничения и возможности подхода, а это хорошо делать с развязанными руками.
С обычной явской VM я этот вес не подниму точно. С таким подходом — поднял до уровня proof of concept. То есть — пока оно себя оправдывает. Мне, кроме всего, важно понять ограничения и возможности подхода, а это хорошо делать с развязанными руками.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Стек стеком погоняет, или преобразование байткода виртуальной машины Java в байткод машины Фантом ОС