Как стать автором
Обновить
  • по релевантности
  • по времени
  • по рейтингу

Универсализация.

Чулан
На заре текущего поколения ЭВМ (т.е. почти 35 лет назад) было модно говорить об универсализации. Именно как об инструменте универсализации было принято говорить о назначении ОС (во всяком случае, так отложилось у меня в голове). С эрой FAT16, INT21 и нагрянувшем Windows об этом забыли. В конце 90-ых так и вообще многие говорили об этом как об утопии. Последние несколько лет начал замечать, что окольными тропами, огородами народ снова стекается к площади универсализации. Уже с бременем совместимости, с огромными тюками никогда не знавших рефакторинга библиотек и связей… Но всё же.
1. Разные ОС потихоньку, маленькими шажками начинают экспериментировать с подключением драйверов друг друга. FreeBSD умеет некоторые Windows NDIS драйвера, Linux тоже, FreeBSD разрабатывает врапер для Linux-драйверов. Xen. Xen стали всё чаще использовать как универсальный интерфейс периферии.
Правда, железо становится всё более и более закрытым. Видимо, нужно появление нового «IBM PC». Дешёвого и открытого.
2. Появляются и уживаются негласные стандарты. MVC там всякие, OpenDoc, PDF, Flash, SiteMap, браузеры, наконец-то, пришли хотя бы к устному соглашению.
3. Байткод. Платформонезависимый байткод. Это практически поветрие, пик моды. Да, к чему тут байткод? Распределённость в неоднородной среде, мобильность и совместимость.
Всего голосов 2: ↑2 и ↓0 +2
Просмотры 285
Комментарии 0

Самая короткая запись асинхронных вызовов в tornado или патчим байткод в декораторе

Python *
Сложный асинхронный обработчик в tornado иногда расползается на десятки callback функций, из-за чего становится трудно воспринимать и модифицировать код. Поэтому существует модуль tornado.gen, позволяющий писать обработчик как генератор. Но много yield gen.Task(...) тоже выглядит не очень. Поэтому в порыве бреда я написал упрощающий запись декоратор:
До После
@asynchronous
@gen.engine
def get(self):
    result, status = yield gen.Task(
        db.users.find_one, {
            '_id': ObjectId(user_id),
        },
    )
@asynchronous
@gen.engine
@shortgen
def get(self):
    result, status << db.users.find_one_e({
        '_id': ObjectId(user_id),
        },
    )

Читать дальше →
Всего голосов 26: ↑24 и ↓2 +22
Просмотры 5.9K
Комментарии 18

Байткод

Разработка веб-сайтов *IT-стандарты *
Перевод
Размышляя о софтварном аде и прочих неурядицах с современными операционными системами я наткнулся на интересную статью о байткоде и о том в каких неожиданных местах он может использоваться. Мне кажется эта статья перекликается с вышеупомянутыми, поэтому решил сделать перевод и выложить здесь. Это мой первый перевод на хабре, так что не судите строго. Если есть какие-то замечания по переводу, ошибкам и т.п. просьба писать в личку.

Какой байткод является наиболее используемым в мире? Java (JVM bytecode)? .NET (CLI)? Flash (AVM1\AVM2)? Нет. Есть несколько байткодов которые вы используете каждый день, просто включив компьютер, или планшет, или даже телефон. Вам даже не нужно запускать приложения или посещать какую-нибудь страницу в сети Интернет.

Почитать о байткоде
Всего голосов 66: ↑61 и ↓5 +56
Просмотры 24K
Комментарии 18

Компиляция Try/Catch/Finally для JVM

Java *
Перевод

Вместо введения


Автор статьи, Alan Keefer1, является главным архитектором компании Guidewire Software2, разрабатывающей программное обеспечение для страхового бизнеса. Еще будучи старшим разработчиком, он участвовал в работе над языком Gosu3. В частности, Алан занимался вопросами компиляции языка в байт-код Java.

Данная статья написана в 2009 году и посвящена деталям реализации try/catch/finally в JVM версии 1.6. Для ее прочтения необходимо иметь базовые знания синтаксиса Java, а также понимать назначение байт-кода, простыни которого лежат под катом. Также в конце статьи приведен ряд примеров, похожих на каверзные задачи SCJP.

Внутренности JVM


Одной из вещей, над которой по целому ряду причин мы сейчас работаем, является компиляция нашего «домашнего» языка в байт-код Java. (Для справки: не могу сказать, когда мы закончим. Даже примерно. Даже попадет ли он в будущие релизы.) Веселье заключается в изучении внутренностей JVM, а также поиске всех долбанутых острых углов собственного языка. Но больше всего «веселья» и острых углов доставляют такие операторы, как try/catch/finally. Поэтому, на этот раз, я не буду вдаваться в философию или аджайл. Вместо этого я углублюсь в JVM, куда большинству не требуется (или не хочется) углубляться.

Если бы две недели назад вы спросили меня о finally-блоках, я бы предположил, что их обработка реализована в JVM: это базовая часть языка, она должна быть встроенной, не так ли? Каково же было мое удивление, когда я узнал: нет, не так. На самом деле finally-блоки просто подставляются во все возможны места после try- или связанных с ним catch-блоков. Эти блоки оборачиваются в «catch(Throwable)», который повторно выбросит исключение после того, как finally-блок закончит работу. Осталось только подкрутить таблицу исключений, чтобы подставленные finally-блоки были пропущены. Ну как? (Небольшой нюанс: до версии JVM 1.6 для оператора finally, по всей видимости, использовались подпограммы вместо полной подстановки. Но сейчас мы говорим о версии 1.6, к которой все вышесказанное применимо.)
Читать дальше →
Всего голосов 29: ↑27 и ↓2 +25
Просмотры 21K
Комментарии 15

Пул констант

Java *
Tutorial
Многие знают, что в каждом .class-файле есть замечательная структура данных, которая называется пулом констант. Но далеко не каждый Java-разработчик, глядя на исходник, сможет даже примерно оценить, сколько констант будет создано в пуле.

Возьмём, к примеру, такой код:

System.out.println("Hello World!");

Он транслируется в три инструкции байткода: getstatic (для загрузки статического поля System.out), ldc (для загрузки константной строки «Hello World!») и invokevirtual (для выполнения виртуальной функции println). Попробуйте прикинуть, сколько констант нужно для того, чтобы этот код работал.
Читать дальше →
Всего голосов 48: ↑46 и ↓2 +44
Просмотры 24K
Комментарии 16

TeaVM — ещё один способ запускать Java в браузере

Java *Компиляторы *Kotlin *
Уважаемые читатели! Хочу поделиться с вами своим open-source проектом, над которым я работаю в своё свободное время уже достаточно давно, TeaVM. TeaVM представляет собой транслятор из байткода Java в JavaScript. Существует несколько попыток создать JVM на JavaScript, одна из самых удачных — Doppio. Однако, кроме академической, никакой ценности они не представляют, так как скорость интерпретации байт-кода оставляет желать лучшего. Более того, для интерпретации байткода необходимо как минимум загрузить этот байткод в браузер, а это вырождается в загрузку десятков мегабайт class-файлов.

В отличие от них, TeaVM не интерпретирует байткод, а генерирует JavaScript, который выполняет ровно то, что делал бы байткод, будь он запущен в реальной JVM. Проще говоря, TeaVM декомпилирует байткод Java, но не обратно в Java, а в JavaScript. Разумеется, всё это верно до определённых пределов. Во-первых, в JavaScript попросту отсутствуют некоторые вещи, привычные Java-разработчикам, такие как потоки, полноценная поддержка Юникода (например, поддержка классов символов, регулярные выражения), блокирующий ввод-вывод. Во-вторых, это обусловлено требованиями, которые я предъявлял к компилятору. Например, в TeaVM очень ограничена поддержка reflection. Это следствие одного из преимуществ TeaVM — сравнительно небольшой размер генерируемого файла. Нет, TeaVM не генерирует минимально возможный JavaScript, однако и не станет генерировать огромные многомегабайтные скрипты на каждый чих. Reflection делает невозможным какой-либо статический анализ, поэтому было принято решение от него отказаться.

Прежде чем я продолжу, я хочу для начала показать, на что способен TeaVM. Во-первых, он способен в реальном времени симулировать физику. Во-вторых, он ещё способен по этой физике рисовать красивые картинки в Canvas. Можно увидеть, что JavaScript-файлы сравнительно небольшие. Кстати, обсчёт физики я сам не реализовывал, я всего лишь взял имеющуюся библиотеку JBox2D.
Читать дальше →
Всего голосов 33: ↑33 и ↓0 +33
Просмотры 16K
Комментарии 53

Как растаращить class-файл

Ненормальное программирование *Java *Кодобред
Обычно при компиляции Java-файла получаются .class-файлы примерно того же размера, что и исходник. Меня заинтересовало, можно ли по небольшому исходнику сделать .class-файл, который больше, сильно больше исходника.

Можно поискать какие-то короткие конструкции языка, которые компилируются в длинные цепочки байткода, но линейный прирост меня не устраивал. Я сразу подумал про компиляцию finally-блоков: про неё уже писали на Хабре. Если вкратце, то для каждого finally-блока при непустом try-блоке создаётся минимум два варианта в байткоде: для случая нормального завершения try-блока и для случая завершения с исключением. В последнем случае исключение сохраняется в новую локальную переменную, выполняется код finally, затем исключение достаётся из локальной переменной и перебрасывается. А что если внутри finally снова разместить try-finally и так далее? Результат превзошёл все ожидания.
Читать дальше →
Всего голосов 111: ↑106 и ↓5 +101
Просмотры 43K
Комментарии 63

Компиляция вложенных классов: javac и ecj

Java *
Как известно, в языке Java существуют вложенные (nested) классы, объявленные внутри другого класса. Их даже четыре разновидности — статические вложенные, внутренние (inner), локальные (local) и анонимные (anonymous) (в этой статье мы не затрагиваем лямбда-выражения, появившиеся в Java 8). Всех их объединяет одна интересная особенность: виртуальная машина Java не имеет понятия об особенном статусе этих классов. С её точки зрения это обычные классы, расположенные в том же пакете, что и внешний класс. Вся работа по преобразованию вложенных классов в обычные ложится на компилятор. И здесь любопытно посмотреть, как разные компиляторы с ней справляются. Мы посмотрим на поведение javac 1.8.0.20 и компилятора ecj из Eclipse JDT Core 3.10 (идёт в комплекте с Eclipse Luna).
Читать дальше →
Всего голосов 18: ↑18 и ↓0 +18
Просмотры 12K
Комментарии 10

Инстанцировать не инстанциируемое

Java *
Идея этого топика родилась из этого комментария.

Итак имеем: класс без конструкторов, необходимо создать экземпляр этого класса. На Java такого сделать нельзя, так что придется напрямую манипулировать байткодом. Идея состоит в том, чтобы вызвать NEW, но при этом не вызывать <init>. Но тут есть трудность, спецификация JVM говорит что так делать нельзя,
но очень хочется
Всего голосов 18: ↑18 и ↓0 +18
Просмотры 12K
Комментарии 16

Компиляция и декомпиляция try-with-resources

Java *
Компиляция и декомпиляция try-with-resources, или рассказ о том, как я фиксил баг и что из этого вышло.

Введение


PITestКакое-то время назад backlog рабочего проекта почти опустел, и вверх всплыли различного рода исследовательские задачи. Одна из них звучала весьма интригующе: прикрутить к проекту мутационное тестирования используя PITest. На Хабре уже есть весьма подробный обзор этой библиотеки (с примерами и картинками). Пересказывать эту статью своими словами я не буду, но все же рекомендую с ней предварительно ознакомиться.

Признаюсь, что идеей мутационного тестирования я загорелся. Почти без дополнительных усилий получить инструмент поиска потенциально опасных мест кода — оно того стоит! Я без промедления взялся за дело. На тот момент библиотека была относительно молодой, как следствие — весьма сырой: здесь нужно немного пошаманить с конфигурацией maven’а, там — пропатчить плагин для Sonar’а. Однако через некоторое время я все же смог проверить проект целиком. Результат: сотни выживших мутаций! Эволюция в масштабе на нашем build-сервере.

Засучив рукава я погрузился в работу. В одних тестах не хватает верификаций заглушек, в других вместо логики вообще непонятно что тестируется. Правим, улучшаем, переписываем. В общем, процесс пошел, но число выживших мутаций убывало не так стремительно, как хотелось. Причина была проста: PIT давал огромное количество ложных срабатываний на блоке try-with-resources. Недолгие поиски показали, что баг известен, но до сих пор не исправлен. Что ж, код библиотеки открыт. От чего бы не склонировать его и не посмотреть, в чем же дело?
Читать дальше →
Всего голосов 25: ↑25 и ↓0 +25
Просмотры 14K
Комментарии 6

Сборка мусора в персистентной модели: от терабайта и дальше

Системное программирование *Компиляторы *
Привет всем. Продолжу о Фантоме. Для понимания полезно прочесть статью про персистентную оперативку, а так же общую статью про Фантом на Открытых Системах. Но можно и так.

Итак, мы имеем ОС (или просто среду, не важно), которая обеспечивает прикладным программам персистентную оперативную память, и вообще персистентную «жизнь». Программы живут в общем адресном пространстве с управляемыми (managed) пойнтерами, объектной байткод-машиной, не замечают рестарта ОС и, в целом, счастливы.

Очевидно, что такой среде нужна сборка мусора. Но — какая?

Есть несколько проблем, навязанных спецификой.

Во-первых, теоретически, объём виртуальной памяти в такой среде огромен — терабайты, всё содержимое диска. Ведь мы отображаем в память всё и всегда.

Во-вторых, нас категорически не устраивают stop the world алгоритмы. Если для обычного процесса остановка в полсекундны может быть приемлема, то для виртуальной памяти, которая, большей частью, на диске, это будут уже полчаса, а то как бы не полсуток!

Наконец, если считать, что полная сборка мусора составляет полсуток, нас, наверное, это не устроит — было бы здорово иметь какой-то быстрый процесс сбора мусора, хотя бы и не полностью честный, пусть он часть мусора теряет, но если удаётся быстро вернуть 90% — уже хорошо.

Тут нужна оговорка. Вообще говоря, в системе, которая располагает парой терабайт виртуальной памяти, это не так уж критично — даже если не делать освобождение памяти полсуток, возможно, не так много и набежит — ну, например, истратится 2-3, ну 5 гигабайт, ну даже и 50 гигабайт — не жалко, диск большой.

Но, скорее всего, это приведёт к большой фрагментации памяти — множество локальных переменных окажутся раскиданы по многим далеко расположенным страницам, при этом высока вероятность того, что небольшие вкрапления актуальной информации будут перемежены с тоннами неактуального мусора, что сильно повысит нагрузку на оперативную память.

Ок, итого у нас две задачи.
Читать дальше →
Всего голосов 39: ↑38 и ↓1 +37
Просмотры 11K
Комментарии 26

Kotlin, компиляция в байткод и производительность (часть 1)

Блог компании ИНФОРИОН Программирование *Java *Компиляторы *Kotlin *


О Kotlin последнее время уже очень много сказано (особенно в совокупности с последними новостями c Google IO 17), но в то же время не очень много такой нужной информации, во что же компилируется Kotlin.
Давайте подробнее рассмотрим на примере компиляции в байткод JVM.

Это первая часть публикации. Вторую можно посмотреть тут

Процесс компиляции это довольно обширная тема и чтобы лучше раскрыть все ее нюансы я взял большую часть примеров компиляции из выступления Дмитрия Жемерова: Caught in the Act: Kotlin Bytecode Generation and Runtime Performance. Из этого же выступления взяты все бенчмарки. Помимо ознакомления с публикацией, настоятельно рекомендую вам еще и посмотреть его выступление. Некоторые вещи там рассказаны более подробно. Я же больше внимания акцентирую именно на компиляции языка.

Содержание:


Функции на уровне файла
Primary конструкторы
data классы
Свойства в теле класса
Not-null типы в публичных и приватных методах
Функции расширения (extension functions)
Тела методов в интерфейсах
Аргументы по умолчанию
Лямбды

Но прежде чем рассмотрим основные конструкции языка и то, в какой байткод они компилируются, нужно упомянуть о том, как непосредственно происходит сама компиляция языка:
Читать дальше →
Всего голосов 17: ↑16 и ↓1 +15
Просмотры 23K
Комментарии 15

Kotlin, компиляция в байткод и производительность (часть 2)

Блог компании ИНФОРИОН Программирование *Java *Компиляторы *Kotlin *


Это продолжение публикации. Первую часть можно посмотреть тут

Содержание:


Циклы
When
Делегаты
Object и companion object
lateinit свойства
coroutines
Выводы
Читать дальше →
Всего голосов 12: ↑11 и ↓1 +10
Просмотры 18K
Комментарии 5

Сравнительный анализ некоторых Java-декомпиляторов

Блог компании Ростелеком-Солар Программирование *Java *Реверс-инжиниринг *Софт


В этой статье будут рассмотрены четыре декомпилятора — Fernflower, CFR, Procyon и jadx — и произведено их сравнение по нескольким параметрам.


Дисклеймер: сравнение неформальное и не претендует на научность. Скорее, это просто обзор всех актуальных (на осень 2019) декомпиляторов Java-байткода.


Автор — Анна Явейн (brontozyablik), разработчица Solar appScreener

Читать дальше →
Всего голосов 27: ↑26 и ↓1 +25
Просмотры 6.9K
Комментарии 18

Как мы обошли bytenode и декомпилировали байткод Node.js (V8) в Ghidra

Блог компании Positive Technologies Информационная безопасность *C++ *Node.JS *Реверс-инжиниринг *

«Да я роботов по приколу изобретаю!» Рик Санчес

Многим известно, что в 2019 году АНБ решило предоставить открытый доступ к своей утилите для дизассемблирования (реверс-инжиниринга) под названием Ghidra. Эта утилита стала популярной в среде исследователей благодаря высокой «всеядности». Данный материал открывает цикл статей, посвященных плагину ghidra_nodejs для Ghidra, разработанному нашей командой (https://github.com/PositiveTechnologies/ghidra_nodejs). Задача плагина — десериализовать содержимое jsc-файлов, дизассемблировать байткод функций и декомпилировать их. В первой статье мы обсудим сущности и байткод движка V8, а также тезисно опишем сам плагин, про который подробно расскажем в последующих статьях.

Рано или поздно все сталкиваются с программами на языке JavaScript, их так и называют скриптами. JavaScript — это полноценный язык со своим стандартом ECMA Script, скрипты которого выполняются не только в браузере, но и на сервере.

Скрипты исполняются с помощью специальной программы, которую называют движком (engine) JavaScript. За годы движкостроения их понапридумывали предостаточно: V8, SpiderMonkey, Chakra, Rhino, KJS, Nashorn и т. д.

Читать далее
Всего голосов 26: ↑26 и ↓0 +26
Просмотры 4.2K
Комментарии 7