From 8ca96633e0b8c8cc829324890b1603889fdd486d Mon Sep 17 00:00:00 2001 From: stepanov Date: Tue, 29 Oct 2024 16:36:29 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BC=D0=B5=D0=BD=D0=B0=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20irr-=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Версии компонент: liblccrt: ecomp.r29.144265 плагин liblccopt: ecomp.r29.143691 - ecomp.r29.144265 --- lib/irr/lccrt_irrjit.h | 264 ++++++++++++++++++++--------------------- lib/irr/lccrt_jit.c | 36 +++--- lib/irr/lccrt_jit.h | 134 ++++++++++----------- lib/irr/lccrt_jite2k.c | 14 +-- lib/irr/lccrt_utils.c | 6 +- 5 files changed, 227 insertions(+), 227 deletions(-) diff --git a/lib/irr/lccrt_irrjit.h b/lib/irr/lccrt_irrjit.h index d030376..1bec016 100644 --- a/lib/irr/lccrt_irrjit.h +++ b/lib/irr/lccrt_irrjit.h @@ -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; diff --git a/lib/irr/lccrt_jit.c b/lib/irr/lccrt_jit.c index c095878..3dbf92b 100644 --- a/lib/irr/lccrt_jit.c +++ b/lib/irr/lccrt_jit.c @@ -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) diff --git a/lib/irr/lccrt_jit.h b/lib/irr/lccrt_jit.h index d094697..ff55ba7 100644 --- a/lib/irr/lccrt_jit.h +++ b/lib/irr/lccrt_jit.h @@ -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, diff --git a/lib/irr/lccrt_jite2k.c b/lib/irr/lccrt_jite2k.c index 19948cc..f5c8fa1 100644 --- a/lib/irr/lccrt_jite2k.c +++ b/lib/irr/lccrt_jite2k.c @@ -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) ) diff --git a/lib/irr/lccrt_utils.c b/lib/irr/lccrt_utils.c index ab0b5c1..8907701 100644 --- a/lib/irr/lccrt_utils.c +++ b/lib/irr/lccrt_utils.c @@ -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)