Internalize rb_mjit_unit definition again

Fixed a TODO in b9007b6c54
This commit is contained in:
Takashi Kokubun 2020-02-26 00:27:28 -08:00
Родитель daf7c48d88
Коммит 69f377a3d6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 6FFC433B12EE23DD
7 изменённых файлов: 42 добавлений и 37 удалений

5
iseq.c
Просмотреть файл

@ -359,10 +359,9 @@ rb_iseq_mark(const rb_iseq_t *iseq)
} }
#if USE_MJIT #if USE_MJIT
if (body->jit_unit && body->jit_unit->cc_entries != NULL) { if (body->jit_unit && mjit_iseq_cc_entries(body) != NULL) {
// TODO: move to mjit.c?
for (unsigned int i=0; i<body->ci_size; i++) { for (unsigned int i=0; i<body->ci_size; i++) {
const struct rb_callcache *cc = body->jit_unit->cc_entries[i]; const struct rb_callcache *cc = mjit_iseq_cc_entries(body)[i];
if (cc != NULL) { if (cc != NULL) {
rb_gc_mark((VALUE)cc); // pindown rb_gc_mark((VALUE)cc); // pindown
} }

8
mjit.c
Просмотреть файл

@ -45,7 +45,7 @@ mjit_copy_job_handler(void *data)
CRITICAL_SECTION_FINISH(3, "in mjit_copy_job_handler"); CRITICAL_SECTION_FINISH(3, "in mjit_copy_job_handler");
return; return;
} }
else if (job->iseq == NULL) { // ISeq GC notified in mjit_mark_iseq else if (job->iseq == NULL) { // ISeq GC notified in mjit_free_iseq
job->finish_p = true; job->finish_p = true;
CRITICAL_SECTION_FINISH(3, "in mjit_copy_job_handler"); CRITICAL_SECTION_FINISH(3, "in mjit_copy_job_handler");
return; return;
@ -1019,6 +1019,12 @@ mjit_mark(void)
RUBY_MARK_LEAVE("mjit"); RUBY_MARK_LEAVE("mjit");
} }
const struct rb_callcache **
mjit_iseq_cc_entries(const struct rb_iseq_constant_body *const body)
{
return body->jit_unit->cc_entries;
}
// A hook to update valid_class_serials. // A hook to update valid_class_serials.
void void
mjit_add_class_serial(rb_serial_t class_serial) mjit_add_class_serial(rb_serial_t class_serial)

30
mjit.h
Просмотреть файл

@ -70,35 +70,6 @@ struct rb_mjit_compile_info {
bool disable_inlining; bool disable_inlining;
}; };
// The unit structure that holds metadata of ISeq for MJIT.
struct rb_mjit_unit {
// Unique order number of unit.
int id;
// Dlopen handle of the loaded object file.
void *handle;
rb_iseq_t *iseq;
#ifndef _MSC_VER
// This value is always set for `compact_all_jit_code`. Also used for lazy deletion.
char *o_file;
// true if it's inherited from parent Ruby process and lazy deletion should be skipped.
// `o_file = NULL` can't be used to skip lazy deletion because `o_file` could be used
// by child for `compact_all_jit_code`.
bool o_file_inherited_p;
#endif
#if defined(_WIN32)
// DLL cannot be removed while loaded on Windows. If this is set, it'll be lazily deleted.
char *so_file;
#endif
// Only used by unload_units. Flag to check this unit is currently on stack or not.
char used_code_p;
struct list_node unode;
// mjit_compile's optimization switches
struct rb_mjit_compile_info compile_info;
// captured CC values, they should be marked with iseq.
const struct rb_callcache **cc_entries; // size: iseq->body->ci_size
};
typedef VALUE (*mjit_func_t)(rb_execution_context_t *, rb_control_frame_t *); typedef VALUE (*mjit_func_t)(rb_execution_context_t *, rb_control_frame_t *);
RUBY_SYMBOL_EXPORT_BEGIN RUBY_SYMBOL_EXPORT_BEGIN
@ -122,6 +93,7 @@ extern struct mjit_cont *mjit_cont_new(rb_execution_context_t *ec);
extern void mjit_cont_free(struct mjit_cont *cont); extern void mjit_cont_free(struct mjit_cont *cont);
extern void mjit_add_class_serial(rb_serial_t class_serial); extern void mjit_add_class_serial(rb_serial_t class_serial);
extern void mjit_remove_class_serial(rb_serial_t class_serial); extern void mjit_remove_class_serial(rb_serial_t class_serial);
const struct rb_callcache ** mjit_iseq_cc_entries(const struct rb_iseq_constant_body *const body);
// A threshold used to reject long iseqs from JITting as such iseqs // A threshold used to reject long iseqs from JITting as such iseqs
// takes too much time to be compiled. // takes too much time to be compiled.

Просмотреть файл

@ -393,7 +393,7 @@ precompile_inlinable_iseqs(FILE *f, const rb_iseq_t *iseq, struct compile_status
if (insn == BIN(opt_send_without_block)) { // `compile_inlined_cancel_handler` supports only `opt_send_without_block` if (insn == BIN(opt_send_without_block)) { // `compile_inlined_cancel_handler` supports only `opt_send_without_block`
CALL_DATA cd = (CALL_DATA)body->iseq_encoded[pos + 1]; CALL_DATA cd = (CALL_DATA)body->iseq_encoded[pos + 1];
const struct rb_callinfo *ci = cd->ci; const struct rb_callinfo *ci = cd->ci;
const struct rb_callcache *cc = iseq->body->jit_unit->cc_entries[call_data_index(cd, body)]; // use copy to avoid race condition const struct rb_callcache *cc = mjit_iseq_cc_entries(iseq->body)[call_data_index(cd, body)]; // use copy to avoid race condition
const rb_iseq_t *child_iseq; const rb_iseq_t *child_iseq;
if (has_valid_method_type(cc) && if (has_valid_method_type(cc) &&

Просмотреть файл

@ -135,6 +135,34 @@ typedef intptr_t pid_t;
#define MJIT_TMP_PREFIX "_ruby_mjit_" #define MJIT_TMP_PREFIX "_ruby_mjit_"
// The unit structure that holds metadata of ISeq for MJIT.
struct rb_mjit_unit {
// Unique order number of unit.
int id;
// Dlopen handle of the loaded object file.
void *handle;
rb_iseq_t *iseq;
#ifndef _MSC_VER
// This value is always set for `compact_all_jit_code`. Also used for lazy deletion.
char *o_file;
// true if it's inherited from parent Ruby process and lazy deletion should be skipped.
// `o_file = NULL` can't be used to skip lazy deletion because `o_file` could be used
// by child for `compact_all_jit_code`.
bool o_file_inherited_p;
#endif
#if defined(_WIN32)
// DLL cannot be removed while loaded on Windows. If this is set, it'll be lazily deleted.
char *so_file;
#endif
// Only used by unload_units. Flag to check this unit is currently on stack or not.
char used_code_p;
struct list_node unode;
// mjit_compile's optimization switches
struct rb_mjit_compile_info compile_info;
// captured CC values, they should be marked with iseq.
const struct rb_callcache **cc_entries; // size: iseq->body->ci_size
};
// Linked list of struct rb_mjit_unit. // Linked list of struct rb_mjit_unit.
struct rb_mjit_unit_list { struct rb_mjit_unit_list {
struct list_head head; struct list_head head;
@ -1184,7 +1212,7 @@ mjit_copy_cache_from_main_thread(const rb_iseq_t *iseq, union iseq_inline_storag
job->finish_p = true; job->finish_p = true;
in_jit = true; // Prohibit GC during JIT compilation in_jit = true; // Prohibit GC during JIT compilation
if (job->iseq == NULL) // ISeq GC is notified in mjit_mark_iseq if (job->iseq == NULL) // ISeq GC is notified in mjit_free_iseq
success_p = false; success_p = false;
job->iseq = NULL; // Allow future GC of this ISeq from here job->iseq = NULL; // Allow future GC of this ISeq from here
CRITICAL_SECTION_FINISH(3, "in mjit_copy_cache_from_main_thread"); CRITICAL_SECTION_FINISH(3, "in mjit_copy_cache_from_main_thread");

Просмотреть файл

@ -14,7 +14,7 @@
MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>]; MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>];
% end % end
% # compiler: Use copied cc to avoid race condition % # compiler: Use copied cc to avoid race condition
const struct rb_callcache *captured_cc = body->jit_unit->cc_entries[call_data_index(cd, body)]; const struct rb_callcache *captured_cc = mjit_iseq_cc_entries(body)[call_data_index(cd, body)];
% %
if (!status->compile_info->disable_send_cache && has_valid_method_type(captured_cc)) { if (!status->compile_info->disable_send_cache && has_valid_method_type(captured_cc)) {
const rb_iseq_t *iseq; const rb_iseq_t *iseq;

Просмотреть файл

@ -57,7 +57,7 @@ switch (insn) {
% when *send_compatible_opt_insns % when *send_compatible_opt_insns
% # To avoid cancel, just emit `opt_send_without_block` instead of `opt_*` insn if call cache is populated. % # To avoid cancel, just emit `opt_send_without_block` instead of `opt_*` insn if call cache is populated.
% cd_index = insn.opes.index { |o| o.fetch(:type) == 'CALL_DATA' } % cd_index = insn.opes.index { |o| o.fetch(:type) == 'CALL_DATA' }
if (has_valid_method_type(body->jit_unit->cc_entries[call_data_index((CALL_DATA)operands[<%= cd_index %>], body)])) { if (has_valid_method_type(mjit_iseq_cc_entries(body)[call_data_index((CALL_DATA)operands[<%= cd_index %>], body)])) {
<%= render 'mjit_compile_send', locals: { insn: opt_send_without_block } -%> <%= render 'mjit_compile_send', locals: { insn: opt_send_without_block } -%>
<%= render 'mjit_compile_insn', locals: { insn: opt_send_without_block } -%> <%= render 'mjit_compile_insn', locals: { insn: opt_send_without_block } -%>
break; break;