Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions Python/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,20 +645,23 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz
{
const StencilGroup *group;
// Loop once to find the total compiled size:
size_t code_size = 0;
size_t hot_code_size = 0;
size_t cold_code_size = 0;
size_t data_size = 0;
jit_state state = {0};
for (size_t i = 0; i < length; i++) {
const _PyUOpInstruction *instruction = &trace[i];
group = &stencil_groups[instruction->opcode];
state.instruction_starts[i] = code_size;
code_size += group->code_size;
state.instruction_starts[i] = hot_code_size;
hot_code_size += group->hot_code_size;
cold_code_size += group->cold_code_size;
data_size += group->data_size;
combine_symbol_mask(group->trampoline_mask, state.trampolines.mask);
combine_symbol_mask(group->got_mask, state.got_symbols.mask);
}
group = &stencil_groups[_FATAL_ERROR_r00];
code_size += group->code_size;
hot_code_size += group->hot_code_size;
cold_code_size += group->cold_code_size;
data_size += group->data_size;
combine_symbol_mask(group->trampoline_mask, state.trampolines.mask);
combine_symbol_mask(group->got_mask, state.got_symbols.mask);
Expand All @@ -672,6 +675,7 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz
// Round up to the nearest page:
size_t page_size = get_page_size();
assert((page_size & (page_size - 1)) == 0);
size_t code_size = hot_code_size + cold_code_size;
size_t code_padding = DATA_ALIGN - ((code_size + state.trampolines.size) & (DATA_ALIGN - 1));
size_t padding = page_size - ((code_size + state.trampolines.size + code_padding + data_size + state.got_symbols.size) & (page_size - 1));
size_t total_size = code_size + state.trampolines.size + code_padding + data_size + state.got_symbols.size + padding;
Expand All @@ -693,23 +697,27 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz
}
// Loop again to emit the code:
unsigned char *code = memory;
unsigned char *cold = memory + hot_code_size;
state.trampolines.mem = memory + code_size;
unsigned char *data = memory + code_size + state.trampolines.size + code_padding;
assert(trace[0].opcode == _START_EXECUTOR_r00 || trace[0].opcode == _COLD_EXIT_r00 || trace[0].opcode == _COLD_DYNAMIC_EXIT_r00);
state.got_symbols.mem = data + data_size;
for (size_t i = 0; i < length; i++) {
const _PyUOpInstruction *instruction = &trace[i];
group = &stencil_groups[instruction->opcode];
group->emit(code, data, executor, instruction, &state);
code += group->code_size;
group->emit(code, cold, data, executor, instruction, &state);
code += group->hot_code_size;
cold += group->cold_code_size;
data += group->data_size;
}
// Protect against accidental buffer overrun into data:
group = &stencil_groups[_FATAL_ERROR_r00];
group->emit(code, data, executor, NULL, &state);
code += group->code_size;
group->emit(code, cold, data, executor, NULL, &state);
code += group->hot_code_size;
cold += group->cold_code_size;
data += group->data_size;
assert(code == memory + code_size);
assert(code == memory + hot_code_size);
assert(cold == memory + code_size);
assert(data == memory + code_size + state.trampolines.size + code_padding + data_size);
if (mark_executable(memory, total_size)) {
jit_free(memory, total_size);
Expand Down
Loading
Loading