sfd
Стадии исполнения Lua программы в LuaJIT: лексический разбор, синтаксический разбор, интерпретация, компиляция "горячих" участков кода в трассы, частичное исполнение кода на трассах. Так как наш тест основан на грамматике, то наши программы лексически и синтаксически корректные, они выполняются в виртуальной машине и, возможно, часть Lua-кода компилируется. Вопрос: а как часто работает JIT-компилятор? Мы добавили в тест сбор метрик, которые предоставляет LuaJIT, чтобы понять сколько программ интерпретируется, сколько программ включают компиляцию, как часто происходит выход с трасс и как часто включаются снапшоты (выход в интерпретатор). Такие метрики дали больше контроля над тестированием. Теперь стало понятно, что не все программы интерпретируются успешно. В чем может быть причина? Изначально мы для исполнения кода сгенерированных программ испоьзовали т.н. protected call (lua_pcall), чтобы возможные ошибки исполнения не прерывали тестирование. Мы проанализировали ошибки исполнения и выяснили, что ошибок выполнения очень много. И часть (sic!) ошибок были синтаксическими. Как так, если мы грамматику используем? Дело в том, что в Lua некоторые операторы могут использоваться не в любом месте программы. Например после return не может быть других выражений, break может использоваться не в любом месте программы, оператор variable arguments (...) может использоваться только в основном теле программы или в функциях, в которых один из аргументов это variable argument. Такие ошибки исправили за счет добавления контекста в сериализаторе. Только решение проблем из-за неверного использования return и break позволило избавиться от 42% ошибок. В своем докладе я рассказывал про семантические ошибки в сгенерированных программах. Львиная доля ошибок в сгенерированных программах были из-за нарушения семантики: использование операций над типами, которые эти операции не поддерживают: сложения таблиц, возведение строк в степень и т.д., некорректные значения для оператора for и другие менее редкие проблемы. Решение проблемы с использованием неподдерживаемых операций получилось интересным. В Lua для каждого объекта или типа можно определить метаметод, который позволит применять стандартную Lua операцию для этого объекта или типа. То есть для сложения надо определить метаметод __add, для вычитания __sub и т.д. Если мы реализуем недостающие метаметоды, то выполнение программы не будет прерываться из-за ошибки. Да, такие метаметоды в большинстве своем бесмыссленны, зато какие бенефиты: большая часть программ начинает выполняться и доходит до компиляции, сгенерированные программы чаще используют метаметоды и метатаблицы, это повышает покрытие кода. Ещё один плюс заключается в том, что мы минимально меняем сериализацию, программы остаются такими же, мы только меняем их поведение. Решение нам понравилось и мы его реализовали в тесте. Полученный результат я считаю хороший: до проделанных изменений 61% программ были с ошибками, после всех изменений их количество снизилось до нуля. Если быть совсем точным, то одна ошибка все-таки осталась - main function has more than 200 local variables, но встречается она редко. Покрытие кода для LuaJIT выросло, вырос процент программ с трассами (+44%), процент программ со снапшотами (+40%) и количество программ с прерванными трассами (+31), значит JIT-компилятор работает гораздо чаще и количество переключений между виртуальной машиной и выполнением трасс выросло. Какие выводы из этой работы можно сделать? Работать над генератором программ для тестирования языковых рантаймов можно и нужно, работа нетривиальная, но оно того стоит. Какие-то ошибки исполнения можно исправить статически, а какие-то только в динамике, во время выполнения программы.
3 анализа крови, которые покажут высокий риск инфаркта задолго до катастрофы
Липопропротеин А - комплекс из двух молекул - липопротеина низкой плотности (ХЛНП) и белка аполипопротеина А. В отличие от общего холестерина и холестерина ЛПНП, этот показатель генетически детерминирован и повлиять на его уровень никак нельзя. Уже к 2 годам жизни у человека липопротеин А достигает определённого индивидуального значения и не меняется в течение всей жизни. У разных людей этот показатель может отличаться в 1000 раз. В человеческих популяциях уровень липопротеина А также имеет существенные различия...