Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question about understand interp generate transform code #109072

Open
srxqds opened this issue Oct 21, 2024 · 1 comment
Open

question about understand interp generate transform code #109072

srxqds opened this issue Oct 21, 2024 · 1 comment
Labels
area-Codegen-Interpreter-mono question Answer questions and provide assistance, not an issue with source code or documentation.
Milestone

Comments

@srxqds
Copy link
Contributor

srxqds commented Oct 21, 2024

mono interp transfer il code to opcode in generate function:

generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, MonoGenericContext *generic_context, MonoError *error)

theTransformData allocate stack at below:

td->stack = (StackInfo*)g_malloc0 ((header->max_stack + 1) * sizeof (td->stack [0]));
td->stack_capacity = header->max_stack + 1;
td->sp = td->stack;
td->max_stack_height = 0;
td->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
td->current_il_offset = -1;
if (!generate_code (td, method, header, generic_context, error))

and will store the custom data in data_items:

rtm->data_items = td->data_items;

at end of the function generate, I found the opcode or data_items will copy to InterpMethod in below code:

rtm->clauses = (MonoExceptionClause*)imethod_alloc0 (td, header->num_clauses * sizeof (MonoExceptionClause));
memcpy (rtm->clauses, header->clauses, header->num_clauses * sizeof(MonoExceptionClause));
rtm->code = (gushort*)td->new_code;
rtm->init_locals = header->init_locals;
rtm->num_clauses = header->num_clauses;
for (guint i = 0; i < header->num_clauses; i++) {
MonoExceptionClause *c = rtm->clauses + i;
int end_off = c->try_offset + c->try_len;
c->try_offset = get_native_offset (td, c->try_offset);
c->try_len = get_native_offset (td, end_off) - c->try_offset;
g_assert ((c->try_offset + c->try_len) <= code_len_u16);
end_off = c->handler_offset + c->handler_len;
c->handler_offset = get_native_offset (td, c->handler_offset);
c->handler_len = get_native_offset (td, end_off) - c->handler_offset;
g_assert (c->handler_len >= 0 && (c->handler_offset + c->handler_len) <= code_len_u16);
if (c->flags & MONO_EXCEPTION_CLAUSE_FILTER)
c->data.filter_offset = get_native_offset (td, c->data.filter_offset);
}
// When optimized (using the var offset allocator), total_locals_size contains also the param area.
// When unoptimized, the param area is stored in the same order, within the IL execution stack.
g_assert (!td->optimized || !td->max_stack_size);
rtm->alloca_size = td->total_locals_size + td->max_stack_size;
g_assert ((rtm->alloca_size % MINT_STACK_ALIGNMENT) == 0);
rtm->locals_size = td->param_area_offset;
// FIXME: Can't allocate this using imethod_alloc0 as its registered with mono_interp_register_imethod_data_items ()
//rtm->data_items = (gpointer*)imethod_alloc0 (td, td->n_data_items * sizeof (td->data_items [0]));
rtm->data_items = (gpointer*)mono_mem_manager_alloc0 (td->mem_manager, td->n_data_items * sizeof (td->data_items [0]));
memcpy (rtm->data_items, td->data_items, td->n_data_items * sizeof (td->data_items [0]));
mono_interp_register_imethod_data_items (rtm->data_items, td->imethod_items);
rtm->patchpoint_data = td->patchpoint_data;

and copy InterpInst(allocated in interp_add_ins) at generate_compacted_code:

size = interp_compute_native_offset_estimates (td, TRUE);
// Generate the compacted stream of instructions
td->new_code = ip = (guint16*)imethod_alloc0 (td, size * sizeof (guint16));

but I could not found the td->stack been copy before being freed at :

g_free (td->stack);
g_free (td->vars);
g_free (td->renamable_vars);
g_free (td->renamed_fixed_vars);
g_free (td->local_ref_count);
dn_simdhash_free (td->data_hash);
#ifdef ENABLE_EXPERIMENT_TIERED
dn_simdhash_free (td->patchsite_hash);
#endif
g_ptr_array_free (td->seq_points, TRUE);
if (td->line_numbers)
g_array_free (td->line_numbers, TRUE);
g_slist_free (td->imethod_items);
mono_mempool_destroy (td->mempool);

why not these data not restore to InterpMethod or maybe other place restore it?

could you help me? @BrzVlad

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Oct 21, 2024
@BrzVlad
Copy link
Member

BrzVlad commented Oct 21, 2024

td->stack and InterpInst* is information that is used only during compilation time. The list of InterpInst is iterated as the last step of compilation and in generate_compacted_code this list is compacted into an array of guint16 that represents the final generated code.

@vitek-karas vitek-karas added question Answer questions and provide assistance, not an issue with source code or documentation. and removed untriaged New issue has not been triaged by the area owner labels Oct 21, 2024
@vitek-karas vitek-karas added this to the Future milestone Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Codegen-Interpreter-mono question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests

3 participants