MJIT: Convert compact_p flag to an enum
I'm gonna add another type of unit shortly.
This commit is contained in:
parent
bfc225764e
commit
0dc5c117a5
48
mjit.c
48
mjit.c
@ -1104,6 +1104,24 @@ free_list(struct rb_mjit_unit_list *list, bool close_handle_p)
|
||||
list->length = 0;
|
||||
}
|
||||
|
||||
static struct rb_mjit_unit*
|
||||
create_unit(enum rb_mjit_unit_type type)
|
||||
{
|
||||
struct rb_mjit_unit *unit = ZALLOC_N(struct rb_mjit_unit, 1);
|
||||
unit->id = current_unit_num++;
|
||||
unit->type = type;
|
||||
return unit;
|
||||
}
|
||||
|
||||
static struct rb_mjit_unit*
|
||||
create_iseq_unit(const rb_iseq_t *iseq)
|
||||
{
|
||||
struct rb_mjit_unit *unit = create_unit(MJIT_UNIT_ISEQ);
|
||||
unit->iseq = (rb_iseq_t *)iseq;
|
||||
ISEQ_BODY(iseq)->jit_unit = unit;
|
||||
return unit;
|
||||
}
|
||||
|
||||
static void mjit_wait(struct rb_mjit_unit *unit);
|
||||
|
||||
// Check the unit queue and start mjit_compile if nothing is in progress.
|
||||
@ -1130,7 +1148,7 @@ check_unit_queue(void)
|
||||
// Dequeue a unit
|
||||
struct rb_mjit_unit *unit = get_from_list(&unit_queue);
|
||||
if (unit == NULL) return;
|
||||
VM_ASSERT(!unit->compact_p);
|
||||
VM_ASSERT(unit->type == MJIT_UNIT_ISEQ);
|
||||
|
||||
// Run the MJIT compiler synchronously
|
||||
current_cc_ms = real_ms_time();
|
||||
@ -1156,22 +1174,6 @@ check_unit_queue(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Create unit for `iseq`. This function may be called from an MJIT worker.
|
||||
static struct rb_mjit_unit*
|
||||
create_unit(const rb_iseq_t *iseq)
|
||||
{
|
||||
struct rb_mjit_unit *unit = ZALLOC_N(struct rb_mjit_unit, 1);
|
||||
unit->id = current_unit_num++;
|
||||
if (iseq == NULL) { // Compact unit
|
||||
unit->compact_p = true;
|
||||
}
|
||||
else { // Normal unit
|
||||
unit->iseq = (rb_iseq_t *)iseq;
|
||||
ISEQ_BODY(iseq)->jit_unit = unit;
|
||||
}
|
||||
return unit;
|
||||
}
|
||||
|
||||
// Check if it should compact all JIT code and start it as needed
|
||||
static void
|
||||
check_compaction(void)
|
||||
@ -1188,7 +1190,7 @@ check_compaction(void)
|
||||
if (compact_units.length < max_compact_size
|
||||
&& ((!mjit_opts.wait && unit_queue.length == 0 && active_units.length > 1)
|
||||
|| (active_units.length == mjit_opts.max_cache_size && compact_units.length * throttle_threshold <= total_unloads))) { // throttle compaction by total_unloads
|
||||
struct rb_mjit_unit *unit = create_unit(NULL);
|
||||
struct rb_mjit_unit *unit = create_unit(MJIT_UNIT_COMPACT);
|
||||
|
||||
// Run the MJIT compiler synchronously
|
||||
current_cc_ms = real_ms_time();
|
||||
@ -1225,7 +1227,7 @@ mjit_notify_waitpid(int exit_code)
|
||||
// Check the result
|
||||
if (exit_code != 0) {
|
||||
verbose(2, "Failed to generate so");
|
||||
if (!current_cc_unit->compact_p) {
|
||||
if (current_cc_unit->type == MJIT_UNIT_ISEQ) {
|
||||
current_cc_unit->iseq->body->jit_func = (jit_func_t)MJIT_FUNC_FAILED;
|
||||
}
|
||||
free_unit(current_cc_unit);
|
||||
@ -1236,11 +1238,11 @@ mjit_notify_waitpid(int exit_code)
|
||||
// Load .so file
|
||||
char so_file[MAXPATHLEN];
|
||||
sprint_uniq_filename(so_file, (int)sizeof(so_file), current_cc_unit->id, MJIT_TMP_PREFIX, DLEXT);
|
||||
if (current_cc_unit->compact_p) { // Compact unit
|
||||
if (current_cc_unit->type == MJIT_UNIT_COMPACT) {
|
||||
load_compact_funcs_from_so(current_cc_unit, c_file, so_file);
|
||||
current_cc_unit = NULL;
|
||||
}
|
||||
else { // Normal unit
|
||||
else { // MJIT_UNIT_ISEQ
|
||||
// Load the function from so
|
||||
char funcname[MAXPATHLEN];
|
||||
sprint_funcname(funcname, sizeof(funcname), current_cc_unit);
|
||||
@ -1327,7 +1329,7 @@ mjit_add_iseq_to_process(const rb_iseq_t *iseq, const struct rb_mjit_compile_inf
|
||||
}
|
||||
|
||||
ISEQ_BODY(iseq)->jit_func = (jit_func_t)MJIT_FUNC_COMPILING;
|
||||
create_unit(iseq);
|
||||
create_iseq_unit(iseq);
|
||||
if (compile_info != NULL)
|
||||
ISEQ_BODY(iseq)->jit_unit->compile_info = *compile_info;
|
||||
add_to_list(ISEQ_BODY(iseq)->jit_unit, &unit_queue);
|
||||
@ -1363,7 +1365,7 @@ mjit_wait(struct rb_mjit_unit *unit)
|
||||
while (current_cc_pid == initial_pid) {
|
||||
tries++;
|
||||
if (tries / 1000 > MJIT_WAIT_TIMEOUT_SECONDS) {
|
||||
if (!unit->compact_p) {
|
||||
if (unit->type == MJIT_UNIT_ISEQ) {
|
||||
unit->iseq->body->jit_func = (jit_func_t)MJIT_FUNC_FAILED; // C compiler was too slow. Give up.
|
||||
}
|
||||
mjit_warning("timed out to wait for JIT finish");
|
||||
|
18
mjit_c.h
18
mjit_c.h
@ -14,23 +14,35 @@
|
||||
#define NOT_COMPILED_STACK_SIZE -1
|
||||
#define ALREADY_COMPILED_P(status, pos) (status->stack_size_for_pos[pos] != NOT_COMPILED_STACK_SIZE)
|
||||
|
||||
// Type of rb_mjit_unit
|
||||
enum rb_mjit_unit_type {
|
||||
// Single-ISEQ unit for mjit_compile
|
||||
MJIT_UNIT_ISEQ = 0,
|
||||
// All-ISEQ unit for mjit_compact
|
||||
MJIT_UNIT_COMPACT = 1,
|
||||
};
|
||||
|
||||
// The unit structure that holds metadata of ISeq for MJIT.
|
||||
// TODO: Use different structs for ISEQ and COMPACT
|
||||
struct rb_mjit_unit {
|
||||
struct ccan_list_node unode;
|
||||
// Unique order number of unit.
|
||||
int id;
|
||||
// Dlopen handle of the loaded object file.
|
||||
void *handle;
|
||||
// Type of this unit
|
||||
enum rb_mjit_unit_type type;
|
||||
|
||||
// ISEQ for a non-batch unit
|
||||
rb_iseq_t *iseq;
|
||||
// Only used by unload_units. Flag to check this unit is currently on stack or not.
|
||||
bool used_code_p;
|
||||
// True if it's a unit for JIT compaction
|
||||
bool compact_p;
|
||||
// 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;
|
||||
unsigned int cc_entries_size; // ISEQ_BODY(iseq)->ci_size + ones of inlined iseqs
|
||||
// ISEQ_BODY(iseq)->ci_size + ones of inlined iseqs
|
||||
unsigned int cc_entries_size;
|
||||
};
|
||||
|
||||
// Storage to keep data which is consistent in each conditional branch.
|
||||
|
@ -621,9 +621,9 @@ module RubyVM::MJIT
|
||||
unode: [self.ccan_list_node, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), unode)")],
|
||||
id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), id)")],
|
||||
handle: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), handle)")],
|
||||
type: [self.rb_mjit_unit_type, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), type)")],
|
||||
iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), iseq)")],
|
||||
used_code_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), used_code_p)")],
|
||||
compact_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), compact_p)")],
|
||||
compile_info: [self.rb_mjit_compile_info, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), compile_info)")],
|
||||
cc_entries: [CType::Pointer.new { CType::Pointer.new { self.rb_callcache } }, Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), cc_entries)")],
|
||||
cc_entries_size: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_unit *)NULL)), cc_entries_size)")],
|
||||
@ -783,5 +783,9 @@ module RubyVM::MJIT
|
||||
CType::Stub.new(:ccan_list_node)
|
||||
end
|
||||
|
||||
def C.rb_mjit_unit_type
|
||||
CType::Stub.new(:rb_mjit_unit_type)
|
||||
end
|
||||
|
||||
### MJIT bindgen end ###
|
||||
end if RubyVM::MJIT.enabled? && RubyVM::MJIT.const_defined?(:C) # not defined for miniruby
|
||||
|
Loading…
x
Reference in New Issue
Block a user