:
       liblccrt:  ecomp.r29.144265
 liblccopt: ecomp.r29.143691 - ecomp.r29.144265
This commit is contained in:
stepanov 2024-10-29 16:36:29 +03:00
parent f62a02f948
commit 8ca96633e0
5 changed files with 227 additions and 227 deletions

View File

@ -1,5 +1,5 @@
/**
* lccrt.h - пользовательский интерфейс (динамической) компиляции.
* lccrt.h - пользовательский интерфейс (динамической) компиляции.
*
* Copyright (c) 1992-2019 AO "MCST". All rights reserved.
*/
@ -21,7 +21,7 @@ typedef struct lccrt_irr_code_area_r *lccrt_irr_code_area_ptr;
typedef lccrt_irr_code_area_ptr lccrt_irr_ca_ptr;
/**
* Просто буфер.
* Просто буфер.
*/
typedef struct lccrt_irr_buffer_r
{
@ -32,243 +32,243 @@ typedef struct lccrt_irr_buffer_r
} lccrt_irr_buffer_t;
/**
* Элемент двусвязного списка.
* Элемент двусвязного списка.
*/
typedef struct lccrt_irr_edge_link_r
{
lccrt_irr_edge_ptr prev; /* предыдущий элемент списка */
lccrt_irr_edge_ptr next; /* следующий элемент списка */
void *data; /* пользовательские данные */
lccrt_irr_edge_ptr prev; /* предыдущий элемент списка */
lccrt_irr_edge_ptr next; /* следующий элемент списка */
void *data; /* пользовательские данные */
} lccrt_irr_edge_link_t;
/**
* Двусторонняя дуга.
* Двусторонняя дуга.
*/
typedef struct lccrt_irr_edge_r
{
lccrt_irr_edge_link_t src; /* источник дуги */
lccrt_irr_edge_link_t dst; /* приемник дуги */
lccrt_irr_edge_link_t src; /* источник дуги */
lccrt_irr_edge_link_t dst; /* приемник дуги */
lccrt_check_type_t type_check;
} lccrt_irr_edge_t;
/**
* Участок памяти для размещения нативного кода.
* Участок памяти для размещения нативного кода.
*/
typedef struct lccrt_irr_code_area_r
{
lccrt_irr_jr_ptr jr; /* jit-регион */
void *area; /* участок памяти (открытый на исполнение) */
int64_t area_len; /* байтовый размер участка */
int64_t area_use; /* количество байт, использованных от начала участка */
lccrt_irr_jr_ptr jr; /* jit-регион */
void *area; /* участок памяти (открытый на исполнение) */
int64_t area_len; /* байтовый размер участка */
int64_t area_use; /* количество байт, использованных от начала участка */
struct lccrt_irr_code_area_r *prev;
struct lccrt_irr_code_area_r *next;
lccrt_check_type_t type_check;
} lccrt_irr_code_area_t;
/**
* Результат компиляции группы линейных участков с одной точкой входа.
* Результат компиляции группы линейных участков с одной точкой входа.
*/
typedef struct lccrt_irr_code_r
{
void *start_point; /* начало нативного кода */
lccrt_irr_jr_ptr jr; /* jit-регион */
lccrt_irr_node_ptr node; /* стартовый узел группы */
lccrt_irr_edge_ptr nodes; /* множество узлов, из которых был скомпилирован данный нативный код
(источник дуги - данный код, приемник дуги - узел) */
void *start_point; /* начало нативного кода */
lccrt_irr_jr_ptr jr; /* jit-регион */
lccrt_irr_node_ptr node; /* стартовый узел группы */
lccrt_irr_edge_ptr nodes; /* множество узлов, из которых был скомпилирован данный нативный код
(источник дуги - данный код, приемник дуги - узел) */
lccrt_check_type_t type_check;
} lccrt_irr_code_t;
/**
* Данные модуля трансляция виртуального адреса.
* Данные модуля трансляция виртуального адреса.
*/
typedef struct lccrt_irr_resolve_r
{
void *data; /* данные, которые необходимо передать функции трансляции не распределенного адреса */
lccrt_irr_resolve_virt_addr_func_t func; /* функция трансляции не распределенного адреса */
void ***etbls; /* промежуточные таблицы для еще не распределенных адресов */
void **table0; /* корневая таблица трансляции виртуального адреса */
int level; /* количество промежуточных (без листового) уровней трансляции */
int bits; /* количество значащих бит в промежуточной части адреса */
int tail_bits; /* количество значащих бит в листовой части адреса (если
level*bits + tail_bits < 64, то считаем траслируемый адрес
всегда выравненным на недостающее количество бит) */
void *data; /* данные, которые необходимо передать функции трансляции не распределенного адреса */
lccrt_irr_resolve_virt_addr_func_t func; /* функция трансляции не распределенного адреса */
void ***etbls; /* промежуточные таблицы для еще не распределенных адресов */
void **table0; /* корневая таблица трансляции виртуального адреса */
int level; /* количество промежуточных (без листового) уровней трансляции */
int bits; /* количество значащих бит в промежуточной части адреса */
int tail_bits; /* количество значащих бит в листовой части адреса (если
level*bits + tail_bits < 64, то считаем траслируемый адрес
всегда выравненным на недостающее количество бит) */
struct
{
uint64_t vaddr_hi; /* полная старшая часть виртуального адреса последнего обращения */
void **table; /* таблица последнего обращения */
uint64_t vaddr_hi; /* полная старшая часть виртуального адреса последнего обращения */
void **table; /* таблица последнего обращения */
} hash;
} lccrt_irr_resolve_t;
/**
* Данные потока компиляции.
* Данные потока компиляции.
*/
typedef struct
{
pthread_t func; /* данные потока компиляции */
pthread_mutex_t a_sync; /* для передачи сигнала в поток компиляции */
pthread_mutex_t b_sync; /* для приема сигнала из потока компиляции */
lccrt_plugin_t *plg; /* библиотека компиляции Backend Bytecode'а в целевой код */
lccrt_irr_buffer_t buff; /* буфер для формирования Backend Bytecode */
lccrt_irr_node_ptr node; /* линейный участок, переданный потоку компиляции */
lccrt_irr_code_ptr code; /* набор линейных участков, представление которых передано
потоку компиляции */
uint8_t is_ready; /* флаг готовности потока компиляции */
char *exec_mem; /* текущая страница открытая на запись и исполнение */
int64_t exec_index; /* индекс в текущей странице (количество использованных байт) */
int64_t exec_length; /* байтовый размер текущей страницы */
pthread_t func; /* данные потока компиляции */
pthread_mutex_t a_sync; /* для передачи сигнала в поток компиляции */
pthread_mutex_t b_sync; /* для приема сигнала из потока компиляции */
lccrt_plugin_t *plg; /* библиотека компиляции Backend Bytecode'а в целевой код */
lccrt_irr_buffer_t buff; /* буфер для формирования Backend Bytecode */
lccrt_irr_node_ptr node; /* линейный участок, переданный потоку компиляции */
lccrt_irr_code_ptr code; /* набор линейных участков, представление которых передано
потоку компиляции */
uint8_t is_ready; /* флаг готовности потока компиляции */
char *exec_mem; /* текущая страница открытая на запись и исполнение */
int64_t exec_index; /* индекс в текущей странице (количество использованных байт) */
int64_t exec_length; /* байтовый размер текущей страницы */
} lccrt_irr_compile_t;
/**
* Период поиска линейного участка с максимальным счетчиком.
* Период поиска линейного участка с максимальным счетчиком.
*/
#define LCCRT_IRR_COUNTS_CHAIN_MAX (64)
/**
* Данные региона динамической компиляции.
* Данные региона динамической компиляции.
*/
typedef struct lccrt_irr_jit_region_r
{
lccrt_ctx_ptr ctx; /* общий контекст */
const char *arch; /* название целевой архитектуры */
lccrt_irr_resolve_t resolve; /* модуль трансляции виртуального адреса */
/* цепочка для выявления узла с максимальным счетчиком */
lccrt_ctx_ptr ctx; /* общий контекст */
const char *arch; /* название целевой архитектуры */
lccrt_irr_resolve_t resolve; /* модуль трансляции виртуального адреса */
/* цепочка для выявления узла с максимальным счетчиком */
struct
{
lccrt_irr_node_ptr max_node; /* узел с максимальным счетчиком */
lccrt_irr_node_ptr max_node_prev; /* узел с максимальным счетчиком */
uint64_t cur_length; /* текущая длина цепочки */
lccrt_irr_node_ptr max_node; /* узел с максимальным счетчиком */
lccrt_irr_node_ptr max_node_prev; /* узел с максимальным счетчиком */
uint64_t cur_length; /* текущая длина цепочки */
} counts_chain;
lccrt_irr_compile_t comp; /* данные для взаимодействия с компилятором */
uint64_t node_ident; /* идентификатор для следующего линейного участка */
uint64_t oper_ident; /* идентификатор для следующей операции */
uint64_t exec_node_count; /* количество исполненных узлов в интерпретаторе */
lccrt_irr_compile_t comp; /* данные для взаимодействия с компилятором */
uint64_t node_ident; /* идентификатор для следующего линейного участка */
uint64_t oper_ident; /* идентификатор для следующей операции */
uint64_t exec_node_count; /* количество исполненных узлов в интерпретаторе */
struct lccrt_irr_reloc_unit_r *free_relocs;
int8_t is_exit_all; /* возврат после каждого линейного участка */
int8_t is_debug_done; /* по отладочной опции завершено исполнение irr-кода */
lccrt_irr_code_area_ptr code_areas; /* список участков памяти для кода */
lccrt_irr_edge_ptr free_edges; /* список свободных дуг */
int8_t is_exit_all; /* возврат после каждого линейного участка */
int8_t is_debug_done; /* по отладочной опции завершено исполнение irr-кода */
lccrt_irr_code_area_ptr code_areas; /* список участков памяти для кода */
lccrt_irr_edge_ptr free_edges; /* список свободных дуг */
lccrt_check_type_t type_check;
} lccrt_irr_jit_region_t;
#if 0
/**
* Данные региона динамической компиляции.
* Данные региона динамической компиляции.
*/
typedef struct lccrt_irr_code_r
{
lccrt_ctx_ptr ctx; /* общий контекст */
lccrt_ctx_ptr ctx; /* общий контекст */
lccrt_irr_jit_region_ptr jr;
lccrt_irr_node_ptr node; /* исходный узел */
uint64_t phys_addr; /* адрес расположения первой машинной инструкции */
int64_t phys_len; /* байтовый размер машинного кода */
void *relocs; /* ссылка на пользовательские данные (релокейшены указывающие на данный код) */
lccrt_irr_node_ptr node; /* исходный узел */
uint64_t phys_addr; /* адрес расположения первой машинной инструкции */
int64_t phys_len; /* байтовый размер машинного кода */
void *relocs; /* ссылка на пользовательские данные (релокейшены указывающие на данный код) */
lccrt_check_type_t type_check;
} lccrt_irr_code_t;
#endif
/**
* Размер кэша трансляции в контексте исполнения.
* Размер кэша трансляции в контексте исполнения.
*/
#define LCCRT_IRR_EC_DLINKS_LEN (8)
/**
* Данные контекста исполнения кода, полученного в результате компиляции.
* Данные контекста исполнения кода, полученного в результате компиляции.
*/
typedef struct lccrt_irr_execute_context_r
{
lccrt_ctx_ptr ctx; /* общий контекст */
lccrt_ctx_ptr ctx; /* общий контекст */
lccrt_irr_jit_region_ptr jr;
int64_t exit_value; /* возвращаемое значение по завершению исполнения */
int regs_max[LCCRT_IRR_REG_TYPE_LAST]; /* фактические максимальные количества регистров
каждого типа */
uint64_t *ext_regs[LCCRT_IRR_REG_TYPE_LAST]; /* массивы со значениями регистров */
int64_t exit_value; /* возвращаемое значение по завершению исполнения */
int regs_max[LCCRT_IRR_REG_TYPE_LAST]; /* фактические максимальные количества регистров
каждого типа */
uint64_t *ext_regs[LCCRT_IRR_REG_TYPE_LAST]; /* массивы со значениями регистров */
lccrt_check_type_t type_check;
} lccrt_irr_execute_context_t;
/**
* Типы релокейшенов.
* Типы релокейшенов.
*/
typedef enum
{
LCCRT_IRR_RELOC_TYPE_STATIC, /* размещение в байт-код операции LCCRT_IRR_OPER_BRANCHIF_RELOC */
LCCRT_IRR_RELOC_TYPE_STATIC, /* размещение в байт-код операции LCCRT_IRR_OPER_BRANCHIF_RELOC */
LCCRT_IRR_RELOC_TYPE_LAST
} lccrt_irr_reloc_type_t;
/**
* Элемент списка релокейшенов.
* Элемент списка релокейшенов.
*/
typedef struct lccrt_irr_reloc_unit_r
{
struct lccrt_irr_reloc_unit_r *prev; /* ссылка на предыдущий элемент списка */
struct lccrt_irr_reloc_unit_r *next; /* ссылка на следующий элемент списка */
lccrt_irr_node_ptr dst_node; /* линейный участок, на который слинкован релокейшен */
void *data; /* указатель на место размещения релокейшена */
uint64_t data_ident; /* идентификатор места размещения */
int index; /* позиция релокейшена в месте размещения */
lccrt_irr_reloc_type_t type; /* тип релокейшена, на который указывает данный элемент */
struct lccrt_irr_reloc_unit_r *prev; /* ссылка на предыдущий элемент списка */
struct lccrt_irr_reloc_unit_r *next; /* ссылка на следующий элемент списка */
lccrt_irr_node_ptr dst_node; /* линейный участок, на который слинкован релокейшен */
void *data; /* указатель на место размещения релокейшена */
uint64_t data_ident; /* идентификатор места размещения */
int index; /* позиция релокейшена в месте размещения */
lccrt_irr_reloc_type_t type; /* тип релокейшена, на который указывает данный элемент */
lccrt_check_type_t type_check;
} lccrt_irr_reloc_unit_t;
/**
* Данные релокейшена.
* Данные релокейшена.
*/
typedef struct lccrt_irr_reloc_r
{
uint64_t phys_addr; /* адрес первой машинной инструкции, на которую следует передать исполнение
при переходе по релокейшену (данное поле всегда первое поле структуры!) */
uint64_t virt_addr; /* внешний адресный дескриптор */
lccrt_irr_code_ptr code; /* результат компиляции внешнего адресного дескриптора */
lccrt_irr_node_ptr node; /* результат трансляции виртуального адреса */
void *link; /* ссылка на пользовательские данные */
uint64_t phys_addr; /* адрес первой машинной инструкции, на которую следует передать исполнение
при переходе по релокейшену (данное поле всегда первое поле структуры!) */
uint64_t virt_addr; /* внешний адресный дескриптор */
lccrt_irr_code_ptr code; /* результат компиляции внешнего адресного дескриптора */
lccrt_irr_node_ptr node; /* результат трансляции виртуального адреса */
void *link; /* ссылка на пользовательские данные */
lccrt_irr_jit_region_ptr jr;
lccrt_check_type_t type_check;
} lccrt_irr_reloc_t;
/**
* Байт-код представление операции для исполнения в интерпретаторе.
* Байт-код представление операции для исполнения в интерпретаторе.
*/
typedef struct lccrt_irr_bytecode_r
{
uintptr_t name;
uint64_t *a0; /* первый аргумент */
uint64_t *a1; /* второй аргумент */
uint64_t *a2; /* результат или третий аргумент */
lccrt_irr_oper_ptr irr_oper; /* исходная irr-операция */
uint64_t *a0; /* первый аргумент */
uint64_t *a1; /* второй аргумент */
uint64_t *a2; /* результат или третий аргумент */
lccrt_irr_oper_ptr irr_oper; /* исходная irr-операция */
lccrt_check_type_t type_check;
} lccrt_irr_bytecode_t;
/**
* Узел промежуточного irr-представления.
* Узел промежуточного irr-представления.
*/
typedef struct lccrt_irr_node_r
{
lccrt_irr_jr_ptr jr;
uint64_t user_ident; /* внешний идентификатор */
uint64_t ident; /* внутренний идентификатор */
lccrt_irr_oper_ptr beg; /* начальная операция узла */
lccrt_irr_oper_ptr end; /* последняя операция узла */
lccrt_irr_code_ptr code; /* результат компиляции в нативный код */
lccrt_irr_reloc_unit_ptr relocs; /* список релокейшенов, указывающих на данный узел */
uint64_t attrs; /* пользовательские атрибуты узла */
uint64_t exec_count; /* счетчик узла */
uint8_t is_delete; /* узел должен быть удален */
uint64_t user_ident; /* внешний идентификатор */
uint64_t ident; /* внутренний идентификатор */
lccrt_irr_oper_ptr beg; /* начальная операция узла */
lccrt_irr_oper_ptr end; /* последняя операция узла */
lccrt_irr_code_ptr code; /* результат компиляции в нативный код */
lccrt_irr_reloc_unit_ptr relocs; /* список релокейшенов, указывающих на данный узел */
uint64_t attrs; /* пользовательские атрибуты узла */
uint64_t exec_count; /* счетчик узла */
uint8_t is_delete; /* узел должен быть удален */
#ifdef LCCRT_IRR_BYTECODE_E2K
char *e2k_opers[2]; /* цепочки операций, подготовленных для интерпретатора */
char *e2k_opers[2]; /* цепочки операций, подготовленных для интерпретатора */
#else /* !LCCRT_IRR_BYTECODE_E2K */
lccrt_irr_bytecode_t *bytecodes; /* цепочки операций, подготовленных для интерпретатора */
lccrt_irr_bytecode_t *bytecodes; /* цепочки операций, подготовленных для интерпретатора */
#endif /* LCCRT_IRR_BYTECODE_E2K */
/* данные, полученные при компиляции линейного участка */
/* данные, полученные при компиляции линейного участка */
struct
{
void *code; /* адрес начала кода */
lccrt_irr_edge_ptr codes; /* множество групп компиляции, в которые был включен данный узел
(источник дуги - группа, приемник дуги - данный узел) */
void *code; /* адрес начала кода */
lccrt_irr_edge_ptr codes; /* множество групп компиляции, в которые был включен данный узел
(источник дуги - группа, приемник дуги - данный узел) */
} comp;
lccrt_check_type_t type_check;
} lccrt_irr_node_t;
/**
* Итератор операций узла промежуточного irr-представления.
* Итератор операций узла промежуточного irr-представления.
*/
typedef struct lccrt_irr_oper_iter_r
{
@ -279,7 +279,7 @@ typedef struct lccrt_irr_oper_iter_r
} lccrt_irr_oper_iter_t;
/**
* Результат трансляции физического адреса.
* Результат трансляции физического адреса.
*/
typedef struct lccrt_irr_oper_branch_r
{
@ -287,26 +287,26 @@ typedef struct lccrt_irr_oper_branch_r
} lccrt_irr_oper_branch_t;
/**
* Операция промежуточного irr-представления.
* Операция промежуточного irr-представления.
*/
typedef struct lccrt_irr_oper_r
{
lccrt_irr_node_ptr node; /* ссылка на охватывающий узел */
lccrt_irr_oper_ptr prev; /* предыдущая операция в узле */
lccrt_irr_oper_ptr next; /* следующая операция в узле (либо альтернатива-0 перехода) */
lccrt_irr_oper_ptr nextif; /* альтернатива-1 перехода */
lccrt_irr_arg_ptr args; /* массив аргументов */
lccrt_irr_arg_ptr rarg; /* результат */
uint64_t ident; /* внутренний идентификатор операции */
uint64_t func; /* адрес, кода исполняющего операцию для интерпретатора */
lccrt_irr_oper_branch_t *branch; /* дополнительные данные операции типа branch */
int num_args; /* количество аргументов */
lccrt_irr_oper_name_t name; /* название операции */
lccrt_irr_node_ptr node; /* ссылка на охватывающий узел */
lccrt_irr_oper_ptr prev; /* предыдущая операция в узле */
lccrt_irr_oper_ptr next; /* следующая операция в узле (либо альтернатива-0 перехода) */
lccrt_irr_oper_ptr nextif; /* альтернатива-1 перехода */
lccrt_irr_arg_ptr args; /* массив аргументов */
lccrt_irr_arg_ptr rarg; /* результат */
uint64_t ident; /* внутренний идентификатор операции */
uint64_t func; /* адрес, кода исполняющего операцию для интерпретатора */
lccrt_irr_oper_branch_t *branch; /* дополнительные данные операции типа branch */
int num_args; /* количество аргументов */
lccrt_irr_oper_name_t name; /* название операции */
lccrt_check_type_t type_check;
} lccrt_irr_oper_t;
/**
* Типы аргументов.
* Типы аргументов.
*/
typedef enum
{
@ -317,7 +317,7 @@ typedef enum
} lccrt_irr_arg_type_t;
/**
* Аргумент операции промежуточного irr-представления.
* Аргумент операции промежуточного irr-представления.
*/
typedef struct lccrt_irr_arg_r
{
@ -331,12 +331,12 @@ typedef struct lccrt_irr_arg_r
} lccrt_irr_arg_t;
/**
* Регистр промежуточного irr-представления.
* Регистр промежуточного irr-представления.
*/
typedef struct lccrt_irr_reg_r
{
lccrt_irr_reg_type_t type; /* тип регистра */
int64_t addr; /* номер регистра */
lccrt_irr_reg_type_t type; /* тип регистра */
int64_t addr; /* номер регистра */
lccrt_check_type_t type_check;
} lccrt_irr_reg_t;

View File

@ -22,8 +22,8 @@ static lccrt_irr_oper_t lccrt_irr_oper_reloc =
static uint64_t lccrt_irr_bytecode_empty = 0;
/**
* Обновление линейных участков с максимальными счетчиками. Передача в компилятор
* линейного участка. Получение из компилятора готового кода.
* Обновление линейных участков с максимальными счетчиками. Передача в компилятор
* линейного участка. Получение из компилятора готового кода.
*/
void
lccrt_irr_compiler_eval_exec_counts( lccrt_irr_jr_ptr jr, lccrt_irr_node_ptr node)
@ -47,7 +47,7 @@ lccrt_irr_compiler_eval_exec_counts( lccrt_irr_jr_ptr jr, lccrt_irr_node_ptr nod
jr->counts_chain.max_node = node;
}
/* Если есть готовый (скомпилированный) узел, то линкуем его. */
/* Если есть готовый (скомпилированный) узел, то линкуем его. */
if ( jr->comp.is_ready )
{
lccrt_irr_node_ptr comp_node = jr->comp.node;
@ -57,16 +57,16 @@ lccrt_irr_compiler_eval_exec_counts( lccrt_irr_jr_ptr jr, lccrt_irr_node_ptr nod
{
if ( comp_node->is_delete )
{
/* В процессе компиляции было запланировано удаление узла. */
/* В процессе компиляции было запланировано удаление узла. */
lccrt_irr_node_delete( comp_node);
} else
{
lccrt_irr_reloc_unit_ptr ru;
lccrt_irr_reloc_unit_ptr ru_next = 0;
/* Пока берем "простое" решение - обнуляем старые линковки, чтобы
при последующей линковке были установлены ссылки на новую
реализацию узла. */
/* Пока берем "простое" решение - обнуляем старые линковки, чтобы
при последующей линковке были установлены ссылки на новую
реализацию узла. */
for ( ru = node->relocs; ru; ru = ru_next )
{
ru_next = ru->next;
@ -79,7 +79,7 @@ lccrt_irr_compiler_eval_exec_counts( lccrt_irr_jr_ptr jr, lccrt_irr_node_ptr nod
}
}
/* Если компилятор готов, то отдаем ему новый узел. */
/* Если компилятор готов, то отдаем ему новый узел. */
if ( jr->comp.is_ready )
{
lccrt_irr_node_ptr comp_node;
@ -108,7 +108,7 @@ lccrt_irr_compiler_eval_exec_counts( lccrt_irr_jr_ptr jr, lccrt_irr_node_ptr nod
} /* lccrt_irr_compiler_eval_exec_counts */
/**
* Создать группу компиляции.
* Создать группу компиляции.
*/
static void
lccrt_irr_compiler_make_code( lccrt_irr_jr_ptr jr)
@ -122,7 +122,7 @@ lccrt_irr_compiler_make_code( lccrt_irr_jr_ptr jr)
node = jr->comp.node;
jr->comp.code = lccrt_irr_code_new( jr, node);
/* Ищем цепочку линейных участков. */
/* Ищем цепочку линейных участков. */
for ( i = 0, cur_node = node; (i < 7) && cur_node; cur_node = next_node )
{
next_node = 0;
@ -166,7 +166,7 @@ lccrt_irr_compiler_make_code( lccrt_irr_jr_ptr jr)
} /* lccrt_irr_compiler_make_code */
/**
* Положить в буфер reloc-аргумент.
* Положить в буфер reloc-аргумент.
*/
static void
lccrt_irr_compiler_push_arg_reloc( lccrt_irr_jr_ptr jr, lccrt_irr_arg_ptr arg, lccrt_irr_code_ptr code)
@ -203,7 +203,7 @@ lccrt_irr_compiler_push_arg_reloc( lccrt_irr_jr_ptr jr, lccrt_irr_arg_ptr arg, l
} /* lccrt_irr_compiler_push_arg_reloc */
/**
* Положить в буфер стандартный аргумент.
* Положить в буфер стандартный аргумент.
*/
static void
lccrt_irr_compiler_push_arg( lccrt_irr_jr_ptr jr, lccrt_irr_arg_ptr arg)
@ -242,7 +242,7 @@ lccrt_irr_compiler_push_arg( lccrt_irr_jr_ptr jr, lccrt_irr_arg_ptr arg)
} /* lccrt_irr_compiler_push_arg */
/**
* Положить в буфер стандартную операцию.
* Положить в буфер стандартную операцию.
*/
static void
lccrt_irr_compiler_push_oper( lccrt_irr_jr_ptr jr, lccrt_bb_oper_name_t name, lccrt_irr_oper_ptr oper)
@ -265,7 +265,7 @@ lccrt_irr_compiler_push_oper( lccrt_irr_jr_ptr jr, lccrt_bb_oper_name_t name, lc
} /* lccrt_irr_compiler_push_oper */
/**
* Передать группу компиляции во внешний модуль компиляции.
* Передать группу компиляции во внешний модуль компиляции.
*/
static void
lccrt_irr_compiler_make_backend_bytecode( lccrt_irr_jr_ptr jr)
@ -346,7 +346,7 @@ lccrt_irr_compiler_wait_compilation( lccrt_irr_jr_ptr jr)
} /* lccrt_irr_compiler_wait_compilation */
/**
* Поток компиляции линейного участка.
* Поток компиляции линейного участка.
*/
void *
lccrt_irr_jit_region_compile_node( void *vjr)
@ -365,7 +365,7 @@ lccrt_irr_jit_region_compile_node( void *vjr)
pthread_mutex_unlock( &jr->comp.b_sync);
lccrt_irr_compiler_wait_compilation( jr);
// Компилируем узел jr->comp.node
// Компилируем узел jr->comp.node
// ...;
// jr->comp.is_ready = 1;
}
@ -1451,7 +1451,7 @@ lccrt_irr_node_simplify( lccrt_irr_n_ptr node)
} /* lccrt_irr_node_simplify */
/**
* Создание байт-код операнда.
* Создание байт-код операнда.
*/
static uintptr_t
lccrt_irr_oper_make_bytecode_arg( lccrt_irr_execute_context_ptr ec, lccrt_irr_oper_ptr oper, int arg_num)
@ -1498,7 +1498,7 @@ lccrt_irr_oper_make_bytecode_arg( lccrt_irr_execute_context_ptr ec, lccrt_irr_op
} /* lccrt_irr_oper_make_bytecode_arg */
/**
* Создание байткод-операций для исполнения в интерпретаторе.
* Создание байткод-операций для исполнения в интерпретаторе.
*/
static void
lccrt_irr_node_make_bytecodes( lccrt_irr_node_ptr node, lccrt_irr_execute_context_ptr ec)

View File

@ -1,5 +1,5 @@
/**
* lccrt.h - пользовательский интерфейс (динамической) компиляции.
* lccrt.h - пользовательский интерфейс (динамической) компиляции.
*
* Copyright (c) 1992-2021 AO "MCST". All rights reserved.
*/
@ -16,17 +16,17 @@ typedef struct lccrt_link_func_r *lccrt_link_func_ptr;
typedef struct lccrt_link_symt_func_entry_r *lccrt_link_symt_func_entry_ptr;
/**
* Количество полей в структуре lccrt_link_func_t.
* Количество полей в структуре lccrt_link_func_t.
*/
#define LCCRT_LINK_FUNC_FNUM (12)
/**
* Количество полей в структуре lccrt_link_module_t.
* Количество полей в структуре lccrt_link_module_t.
*/
#define LCCRT_LINK_MODULE_FNUM (9)
/**
* Названия для переменных контроля типа.
* Названия для переменных контроля типа.
*/
#define LCCRT_TCHECK_LINK_FUNC __lccrt_link_func_type_check
#define LCCRT_TCHECK_LINK_SYMT_FUNC_ENTRY __lccrt_link_symt_func_entry_type_check
@ -38,7 +38,7 @@ typedef struct lccrt_link_symt_func_entry_r *lccrt_link_symt_func_entry_ptr;
#define LCCRT_TCHECK_LINK_MODULE_S LCCRT_TO_STR( __lccrt_link_module_type_check)
/**
* Переменные контроля типа.
* Переменные контроля типа.
*/
typedef uint64_t lccrt_link_check_type_t;
extern lccrt_link_check_type_t LCCRT_TCHECK_LINK_FUNC;
@ -47,103 +47,103 @@ extern lccrt_link_check_type_t LCCRT_TCHECK_LINK_SYMT_ENTRY;
extern lccrt_link_check_type_t LCCRT_TCHECK_LINK_MODULE;
/**
* Данные для линковки функции, которые добавляются в компилируемый модуль.
* Данные для линковки функции, которые добавляются в компилируемый модуль.
*/
typedef struct lccrt_link_func_r
{
lccrt_link_module_ptr lm; /* информация о модуле, из которого была
выбрана функция в процессе линковки */
const char *name; /* имя функции внутри собственного (!) модуля */
lccrt_function_ptr f; /* ссылка на соответствующую lccrt-функцию (функция создается в runtime'е) */
void **switch_addr; /* адрес переменной, в которой хранится адрес текущей версии
функции */
void *externf_addr; /* интерфейсная функция с именем исходной функции */
void *profgen_addr; /* версия функции с генерацией профиля */
void *baseopt_addr; /* версия функции с оптимизацией, полученная в статике */
uintptr_t *profgen_sum_addr; /* адрес переменной с профилем, собранным функцией генерации профиля */
pthread_mutex_t *profgen_sync_addr; /* адрес мьютекса для синхронизации доступа к профилю */
uintptr_t init_flag; /* флаг проведенной инициализации */
uintptr_t init_sync; /* поле для инициализации мьютекса */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_func_type_check
для контроля типа */
lccrt_link_module_ptr lm; /* информация о модуле, из которого была
выбрана функция в процессе линковки */
const char *name; /* имя функции внутри собственного (!) модуля */
lccrt_function_ptr f; /* ссылка на соответствующую lccrt-функцию (функция создается в runtime'е) */
void **switch_addr; /* адрес переменной, в которой хранится адрес текущей версии
функции */
void *externf_addr; /* интерфейсная функция с именем исходной функции */
void *profgen_addr; /* версия функции с генерацией профиля */
void *baseopt_addr; /* версия функции с оптимизацией, полученная в статике */
uintptr_t *profgen_sum_addr; /* адрес переменной с профилем, собранным функцией генерации профиля */
pthread_mutex_t *profgen_sync_addr; /* адрес мьютекса для синхронизации доступа к профилю */
uintptr_t init_flag; /* флаг проведенной инициализации */
uintptr_t init_sync; /* поле для инициализации мьютекса */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_func_type_check
для контроля типа */
} lccrt_link_func_t;
/**
* Элемент символьной таблицы функций (__lccrt_link_module_symtab_funcs).
* Элемент символьной таблицы функций (__lccrt_link_module_symtab_funcs).
*/
typedef struct lccrt_link_symt_func_entry_r
{
char *name; /* имя функции (внутри текущего lccrt-модуля) */
lccrt_link_func_ptr lf; /* ссылка на данные о линковке функции */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_symt_func_entry_type_check
для контроля типа */
char *name; /* имя функции (внутри текущего lccrt-модуля) */
lccrt_link_func_ptr lf; /* ссылка на данные о линковке функции */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_symt_func_entry_type_check
для контроля типа */
} lccrt_link_symt_func_entry_t;
/**
* Элемент символьной таблицы функций (__lccrt_link_module_symtab).
* Элемент символьной таблицы функций (__lccrt_link_module_symtab).
*/
typedef struct lccrt_link_symt_entry_r
{
char *name; /* имя функции или переменной (внутри текущего lccrt-модуля) */
void *addr; /* фактический адрес этапа исполнения */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_symt_entry_type_check
для контроля типа */
char *name; /* имя функции или переменной (внутри текущего lccrt-модуля) */
void *addr; /* фактический адрес этапа исполнения */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_symt_entry_type_check
для контроля типа */
} lccrt_link_symt_entry_t;
/**
* Данные lccrt-модуля, которые добавляются в компилируемый модуль.
* Данные lccrt-модуля, которые добавляются в компилируемый модуль.
*/
typedef struct lccrt_link_module_r
{
char *name; /* имя модуля */
lccrt_module_ptr m; /* ссылка на соответствующий lccrt-модуль (модуль создается в runtime'е) */
uintptr_t ir_text_size; /* байтовый размер ir в текстовой форме */
char *ir_text; /* ir в текстовой форме */
uintptr_t symt_funcs_len; /* количество символов в символьной таблице функций */
void *symt_funcs; /* символьная таблица функций */
uintptr_t symt_len; /* количество символов в символьной таблице */
void *symt; /* символьная таблица */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_module_type_check
для контроля типа */
char *name; /* имя модуля */
lccrt_module_ptr m; /* ссылка на соответствующий lccrt-модуль (модуль создается в runtime'е) */
uintptr_t ir_text_size; /* байтовый размер ir в текстовой форме */
char *ir_text; /* ir в текстовой форме */
uintptr_t symt_funcs_len; /* количество символов в символьной таблице функций */
void *symt_funcs; /* символьная таблица функций */
uintptr_t symt_len; /* количество символов в символьной таблице */
void *symt; /* символьная таблица */
lccrt_link_check_type_t *type_check; /* адрес __lccrt_link_module_type_check
для контроля типа */
} lccrt_link_module_t;
/**
* Данные связанные с функцией и используемые для динамической компиляции.
* Данные связанные с функцией и используемые для динамической компиляции.
*/
typedef struct lccrt_function_jit_info_r
{
lccrt_context_ptr ctx;
void *code; /* ссылка на исполняемый код (после компиляции метода) */
uint64_t code_len; /* байтовый размер кода */
lccrt_function_ptr src_func; /* целевая функция */
lccrt_var_ptr jit_entry; /* ссылка на lccrt_link_symt_func_entry_t целевой функции */
//lccrt_var_ptr profgen_sum; /* суммарный профиль, насчитанный на функции сбора профиля */
lccrt_var_ptr profgen_tls; /* tls-профиль, насчитанный на функции сбора профиля */
//lccrt_var_ptr profgen_sync; /* мьютекс для синхронизации доступа к суммарному профилю */
void *code; /* ссылка на исполняемый код (после компиляции метода) */
uint64_t code_len; /* байтовый размер кода */
lccrt_function_ptr src_func; /* целевая функция */
lccrt_var_ptr jit_entry; /* ссылка на lccrt_link_symt_func_entry_t целевой функции */
//lccrt_var_ptr profgen_sum; /* суммарный профиль, насчитанный на функции сбора профиля */
lccrt_var_ptr profgen_tls; /* tls-профиль, насчитанный на функции сбора профиля */
//lccrt_var_ptr profgen_sync; /* мьютекс для синхронизации доступа к суммарному профилю */
lccrt_check_type_t type_check;
} lccrt_function_jit_info_t;
/**
* Данные системы динамической компиляции.
* Данные системы динамической компиляции.
*/
typedef struct lccrt_jit_r
{
uintptr_t init_flag; /* флаг проведенной инициализации */
uintptr_t init_sync; /* поле для инициализации мьютекса */
int is_start; /* флаг запуска основной службы */
int is_work; /* флаг продолжения работы */
pthread_mutex_t sync; /* мьютекс для синхронного доступа */
pthread_mutex_t comp_sync; /* мьютекс для синхронного доступа */
pthread_mutex_t exit_sync; /* мьютекс для синхронного доступа */
pthread_t work; /* основная служба */
pthread_t comp; /* служба компиляции */
lccrt_link_func_ptr comp_link_func; /* информация о функции */
int is_comp; /* флаг проведения компиляции */
int line_prof[2]; /* линия связи для сообщений о сборе профиля */
int line_comp[2]; /* линия связи для сообщений о компиляции */
lccrt_context_ptr ctx; /* контекст (для создания данных) */
GHashTable *link_funcs; /* соответствие (фактическийАдрес -> link_func) */
lccrt_check_type_t type_check; /* адрес переменной для контроля типа */
uintptr_t init_flag; /* флаг проведенной инициализации */
uintptr_t init_sync; /* поле для инициализации мьютекса */
int is_start; /* флаг запуска основной службы */
int is_work; /* флаг продолжения работы */
pthread_mutex_t sync; /* мьютекс для синхронного доступа */
pthread_mutex_t comp_sync; /* мьютекс для синхронного доступа */
pthread_mutex_t exit_sync; /* мьютекс для синхронного доступа */
pthread_t work; /* основная служба */
pthread_t comp; /* служба компиляции */
lccrt_link_func_ptr comp_link_func; /* информация о функции */
int is_comp; /* флаг проведения компиляции */
int line_prof[2]; /* линия связи для сообщений о сборе профиля */
int line_comp[2]; /* линия связи для сообщений о компиляции */
lccrt_context_ptr ctx; /* контекст (для создания данных) */
GHashTable *link_funcs; /* соответствие (фактическийАдрес -> link_func) */
lccrt_check_type_t type_check; /* адрес переменной для контроля типа */
} lccrt_jit_t;
extern lccrt_fji_ptr lccrt_fji_new( lccrt_ctx_ptr ctx, lccrt_f_ptr src,

View File

@ -1191,7 +1191,7 @@ lccrt_irr_node_execute_e2k_testcode_func( lccrt_irr_node_execute_e2k_oper_t *e2k
} /* lccrt_irr_node_execute_e2k_testcode_func */
/**
* На текущем линейном участке накоплено NCNT_BOUND срабатываний.
* На текущем линейном участке накоплено NCNT_BOUND срабатываний.
*/
void
lccrt_irr_node_execute_e2k_eval_node_counter_func( lccrt_irr_node_execute_e2k_oper_t *oper)
@ -1223,7 +1223,7 @@ lccrt_irr_node_execute_e2k_eval_node_counter_func( lccrt_irr_node_execute_e2k_op
jr->counts_chain.max_node = node;
}
/* Если есть готовый (скомпилированный) узел, то линкуем его. */
/* Если есть готовый (скомпилированный) узел, то линкуем его. */
if ( jr->comp.is_ready )
{
lccrt_irr_node_ptr comp_node = jr->comp.node;
@ -1233,16 +1233,16 @@ lccrt_irr_node_execute_e2k_eval_node_counter_func( lccrt_irr_node_execute_e2k_op
{
if ( comp_node->is_delete )
{
/* В процессе компиляции было запланировано удаление узла. */
/* В процессе компиляции было запланировано удаление узла. */
lccrt_irr_node_delete( comp_node);
} else
{
lccrt_irr_reloc_unit_ptr ru;
lccrt_irr_reloc_unit_ptr ru_next = 0;
/* Пока берем "простое" решение - обнуляем старые линковки, чтобы
при последующей линковке были установлены ссылки на новую
реализацию узла. */
/* Пока берем "простое" решение - обнуляем старые линковки, чтобы
при последующей линковке были установлены ссылки на новую
реализацию узла. */
for ( ru = node->relocs; ru; ru = ru_next )
{
ru_next = ru->next;
@ -1255,7 +1255,7 @@ lccrt_irr_node_execute_e2k_eval_node_counter_func( lccrt_irr_node_execute_e2k_op
}
}
/* Если компилятор готов, то отдаем ему новый узел. */
/* Если компилятор готов, то отдаем ему новый узел. */
if ( jr->comp.is_ready )
{
if ( (jr->counts_chain.max_node_prev->exec_count > jr->counts_chain.max_node->exec_count) )

View File

@ -40,7 +40,7 @@ lccrt_irr_edge_new( lccrt_irr_jr_ptr jr, void *src, void *dst, lccrt_irr_edge_pt
} /* lccrt_irr_edge_new */
/**
* Удаление дуги.
* Удаление дуги.
*/
void
lccrt_irr_edge_delete( lccrt_irr_jr_ptr jr, lccrt_irr_edge_ptr edge, lccrt_irr_edge_ptr *src_list, lccrt_irr_edge_ptr *dst_list)
@ -87,7 +87,7 @@ lccrt_irr_edge_delete( lccrt_irr_jr_ptr jr, lccrt_irr_edge_ptr edge, lccrt_irr_e
} /* lccrt_irr_edge_delete */
/**
* Увеличение максимального размера буферв.
* Увеличение максимального размера буферв.
*/
void
lccrt_irr_buf_alloc( lccrt_irr_buffer_ptr b, int64_t length)
@ -124,7 +124,7 @@ lccrt_irr_buf_alloc( lccrt_irr_buffer_ptr b, int64_t length)
} /* lccrt_irr_buf_alloc */
/**
* Поместить в буфер очередную порцию данных.
* Поместить в буфер очередную порцию данных.
*/
int64_t
lccrt_irr_buf_push( lccrt_irr_buffer_ptr b, char *data, int64_t length)