# # Этот файл в формате POD. Если вы не привыкли читать POD, вы можете пропустить # файл через "perldoc" для получения обычной текстовой версии. =head1 ЗАГОЛОВОК Подсистема JIT Паррота =head1 ВЕРСИЯ =head2 ТЕКУЩАЯ Maintainer: Daniel Grunblatt Class: Internals PDD Number: 8 Version: 1.3 Status: Developing Last Modified: 26 Nov 2002 PDD Format: 1 Language:English =head1 КРАТКИЙ ОБЗОР Этот PDD описывает подсистему компиляции Паррота Just in Time(Как Раз Вовремя). =head1 ОПИСАНИЕ Подсистема Just In Time(или JIT) переводит файл с байт-кодом в инструкции родного машинного кода и выполняет сгенерированную последовательность. =head1 РЕАЛИЗАЦИЯ В настоящий момент подсистема работает на процессорных системах B, B, B, B, and B и на большинстве операционных системах. Пока поддерживаются только 32-разрядные значения INTVAL. На начальном этапе генерации родного кода вызывается функция B, которая обеспечивает архитектурно-специфический вводный код. Для каждого кода операции Паррота генерируется либо общая последовательность, либо специальная последовательность родного кода. Файлы с расширением F<.jit> предоставляют функции, генерирующие родной код для специальных кодов операций с учетом имеющегося у архитектуры набора инструкций. Если для специального кода операции функция не предоставляется, то выводится общая последовательность родного кода, которая вызывает интерпретатор функций Си, который и реализует код операции. Такой код операции обрабатывается B. Если код операции может вызвать изменения в управляющем потоке, как в случае кодов операций branch и call, то используется расширенная или модифицированная версия общего кода, которая следит за изменениями программного и аппаратного счетчика. Данный тип кода операции обрабатывается B. Во время генерации родного кода могут быть не доступны точные смещения и абсолютные адреса. Это случается для кодов операций ветвления с переходом вперед, когда родный код соответствующий метке перехода еще не сгенерирован. На некоторых платформах вызовы функций выполняются с помощью программных счетчиков относительных адресов. Так как местоположение буфера, хранящего родной код может перемещаться по мере генерации кода(из-за увеличения буфера); относительные адреса могут быть вычислены после того как, гарантируется что буфер больше не будет перемещаться. Для обработки таких ситуаций подсистема JIT использует адресные записи, которые хранят местоположения в родном коде, требующие корректировки. =head1 ФАЙЛЫ =over 4 =item jit/${jitcpuarch}/jit_emit.h Этот файл определяет функции B, B, B, B, B и возможно B. Кроме того, он определяет макросы и статические функции, используемые в файлах F<.jit> для получения двоичного представления родных инструкций. Для перемещения регистров от процессора к Парроту и обратно должны быть реализованы функции B. =item jit/${jitcpuarch}/core.jit Здесь указываются функции, генерирующие родной код для основной части кодов операций Паррота. Для упрощения поддержания функции указываются в формате, который предварительно обрабатывается F для получения действительного исходного файла Си F. Смотрите ниже L. =item include/parrot/jit.h Этот Файл содержит определения общих структур используемых подсистемой JIT. Массив B структур B обеспечивает для каждого кода операции указатель на функцию, которая генерирует родной код. Функция является либо общей функцией B, либо B, либо специальной функцией для кода операции. Функция B похожа на функцию B с добавлением проверки нуля программного счетчика. Функции B как B или B и могут быть реализованы для выполнения родных вызовов vtable (смотрите F для примера). Структура B хранит смещение в родном коде, где должна быть произведена адресная запись, тип требуемой адресной записи и специальная информация необходимая для выполнения параметров записи. Сейчас параметр адресной записи является либо значением типа B, либо указателем на функцию. Структура B хранит данные, используемые вовремя получения и исполнения родного кода. Важной частью данных в этой структуре является массив B, который отображает адреса кодов операций на адреса родного кода. =item jit.c B() является главной программой генератора кода, которая проходит по байт-коду Паррота, вызывая программы, генерирующие код, и заполняя массив B. Этот массив используется подсистемой JIT для выполнения определенного типа адресных записей в родном коде, а также самим родным кодом для преобразования значений программных счетчиков в значения аппаратных счетчиков. Байт-код по сути является массивом элементов размера B с параллельными записями B. На начальном этапе B заполнен смещениями в родном коде, соответствующими кодам операций в байт-коде. Как только генерация кода завершена и применины адресные записи, смещения в родном коде переводятся в абсолютные адреса. Таким образом удается обменять неопределенность затрат неоднократных преобразований смещений во время выполнения на небольшие затраты на начальном этапе. Если архитектура определяет B и B как не нулевые, то эти значения предельного числа используемых регистров отображается на родные регистры процессора. =item jit2h.pl Предварительно обрабатывает файлы .jit для получения F. =back =head1 Определения в jit_emit.h Архитектурно-специфический файл F сообщает некоторые определения и таблицы с помощью F и F. Поэтому структура файла и определения должны следовать специальному синтаксису. =head2 Общая структура #if JIT_EMIT ... emit код #else ... определения #ifndef JIT_IMCC ... инициализация отображений ... и возможно частные статические функции #endif #endif =head2 Определения =over 4 =item INT_REGISTERS_TO_MAP Это число целых регистров для отображения на регистры процессора. Соответствующий B должен быть в точности равен этому числу. Нулевой регистр не может быть в списке. =item FLOAT_REGISTERS_TO_MAP Когда определено, то имеет такой же смысл только для регистров с плавающей точкой. =item PRESERVED_INT_REGS Когда определено, то это число целых регистров предохраняется для вызовов функций. Предохраняемые регистры должны быть первыми в B. Когда неопределено, то подразумеваются, что все регистры являются предохраняемыми для вызовов функций. =item PRESERVED_FLOAT_REGS То же самое только для регистров с плавающей точкой. =item jit_emit_noop(pc) =item JUMP_ALIGN Если B и B определены, B должен иметь маленькое значение, указывающее желаемое выравнивание целей перехода, которое равно B<1 << JUMP_ALIGN>. B повторно вызывается с невыровненым B до тех пор, пока the B не буде иметь желаемое выравнивание. Таким образом функция может выпускать одну однобайтовую инструкцию B или похожую на B инструкцию(последовательность) требуемого размера для достижения необходимого выравнивания. =item ALLOCATE_REGISTERS_PER_SECTION Обычно F выполняет назначение регистров по секционно. Но есть в некоторой степени экспериментальное назначение - по блочно. =item MAP Jit-код, сгенерированный JIT оптимизатором F использует отрицательные числа для отображаемых регистров и положительные для неотображаемых регистров Паррота. Для использования этой особенности определение отображаемых регистров может быть переопределено следующим образом: #define MAP(i) OMAP(i) #undef MAP #define MAP(i) (i) >= 0 : 0 ? OMAP(i) =item EXTCALL Этот макрос, если определен, может заменять, то что считается внешней функцией(external function). По умолчанию определение является: # define EXTCALL(op) (op_jit[*(op)].extcall) JIT/i386 имеет jit'ированные функции vtable, где extcall является номером записи vtable и (JIT/i386) переопределяет B на: # define EXTCALL(op) (op_jit[*(op)].extcall == 1) =back Смотрите действительное применение этих определений в F =head1 Формат файлов .jit Jit-файлы интерпретируются следующим образом: =over 4 =item I { \n I \n } Где I является названием кода операции Паррота и I состоит из кода Си, который может содержать любой из идентификаторов, перечисленных в следующем разделе. Закрывающая фигурная скоька должна находится в первой колонке. =item Строки комментариев Комментарии помечаются I<;>, находящимся в первой колонке и, как и пустые строки, игнорируются. =item Идентификаторы Вообще префиксирование идентификатора символом I<&> дает адрес, а префикс I<*> указывает значение. Так как значение регистров Паррота меняется в течение выполнения кода, то эти значения не могут быть получены через единственную замену идентификатора. B Замещается регистром C, указанным в аргументе I. B Замещается регистром C, указанным в аргументе I. B Замещается регистром C, указанным в аргументе I. B Замещается константой C, указанной в аргументе I. B Замещается константой C, указанной в аргументе I. B I-й целый или регистр с плавайщей точкой отображается в данной секции. ЗАМЕЧАНИЕ: Регистр с физическим номером ноль не может быть отображен. =begin unimp B Замещается на C константы C указанной в n-ом аргументе. B Замещается на C константы C указанной в n-ом аргументе. B Замещается на C константы C указанной в n-ом аргументе. B Замещается на C константы C указанной в n-ом аргументе. B Замещается на C константы C указанной в n-ом аргументе. B Замещается на C константы C указанной в n-ом аргументе. B Замещается на C константы C указанной в n-ом аргументе. =end unimp B Замещается на значение текущего программного счетчика. B<*CUR_OPCODE[n]> Замещается на адрес текущего кода операции байт-кода Паррота. B B Целый или с плавающей точкой регистр временной памяти. =item B