Please enable JavaScript.
Coggle requires JavaScript to display documents.
Компиляция - Coggle Diagram
Компиляция
Этапы
Линковка (компоновка)
Замена импортируемых имен на адреса
Замена внутренних адресов в соответствии со смещением модуля
Оптимизация
Замена хвостовой рекурсии
Случай, когда рекурсивный вызов - последняя инструкция перед возвратом
Безопасное преобразование в цикл
Пропадает необходимость помнить локальные переменные до завершения рекурсивного вызова
Аргументы можно представить в виде переменных, объявленных перед циклом
Удаление "мертвого" (недостижимого) кода
Создание объектного файла
Сохраняются символьные имена импортов
В модуль добавляется таблица адресов экспортируемых имен
Генерируется промежуточный машинный код (для модуля)
Лексический анализ (токенезация)
Перевод строки кода во внутреннее представление компилятора (в последовательность токенов)
Синтаксический анализ (парсинг)
Построение дерева разбора (AST)
Последовательность токенов превращается в иерархические смысловые блоки (в структуру данных)
Семантический анализ
Синтаксически верный код может содержать смысловые ошибки
Проверка типов
Связывание имен с их объявлениями
Высокий уровень на низком
Функция
Вызов и возврат
call adr == push curAdr + jmp adr
ret == pop x + jmp x
Передача параметров через регистры или стек
Запись результата в регистр
Блоки кода, возвращающий управление
База кадра стека
Чтение локальной переменной как
mov ax [bp + 3]
Запоминается для удобства адресации
(обычно в регистр bp)
Используемые регистры должны быть сохранены в стек и восстановлены перед возвратом
Ветвление
Набор блоков кода и инструкций условных переходов к ним
Блок передает управление следующему или завершает ветвление
Цикл
Блок с условным переходом в начало себя
Полиморфизм в ООП
Полиморфный код использует массив указателей полученного объекта (
vtable
)
Наследник предоставляет свою версию
vtable
Для интерфейсов в
vtable
могут лежать строковые имена
Поиск адреса нужной реализации в произвольном объекте
Boolean
Для оптимизации занимает 1 байт, т.к. отсутствует побитовая адресация
В массиве каждый boolean может занимать 1 бит
Язык ассемблера (набор мнемоник)
Синтаксисы
Intel (меняется левый операнд)
AT&T (меняется правый операнд)
Типы команд
Работа с памятью
регистр <-> регистр
регистр <-> ОЗУ
регистр <- литерал
ОЗУ <- литерал
Вычисления в АЛУ
(add r1 r2 == r1 += r2)
Переходы
Изменение указателя инструкции
Условный
Опирается на флаговый регистр, установленный при операции АЛУ
Н-р,
je addr
- jump if equal
Безусловный(
jmp
)
Прерывания
Программные(int)
Обработка/запрет/разрешение аппартных
Макросы
Стек
Для очистки перемещается указатель вершины, память перезапишется при повторном росте
Растет вниз для эффективного использования памяти (по аналогии с тетрадью для двух предметов)
Удобный способ хранить локальные переменные функций при нехватке регистров
Виды
JIT
Требуется программная среда исполнения (виртуальная машина)
Построчная компиляция во время исполнения
Долгий запуск программы
Runtime оптимизации
Основываются на анализе времени выполнения
Перекомпиляция фрагментов
Примеры
Встраивание тел функций
Но дополнительная затрата памяти
Экономия на издержках вызова функций
Расширение пространства возможных оптимизаций
Девиртуализация
Замена виртуального вызова на прямой (в ООП)
AOT
Долгое тестирование изменений при разработке
Компиляция под каждую платформу
Разные API OS
Разные инструкции CPU
Освобождение кучи
Ручное
Большой риск утечек памяти
Риск висячих ссылок (указывающих на пустую/переиспользованную память)
Автоматическое (сборщик мусора)
Включается периодически, действует поэтапно
При AOT-компиляции может подключаться в виде библиотеки
Язык не должен содержать указатели
Любая область памяти потенциально может использоваться по вычисленному адресу
Не каждый указатель используется, как прямая ссылка
Оптимизации
Дефрагментация памяти с обновлением ссылок
Крупные объекты лежат во фрагментированной куче (дорого копировать)
Анализ достижимости объекта по ссылке
Из стека
Из глобальной области
Из другого достижимого объекта