Skip to content

[mypyc] Add cleanup at end of init function #10590

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

Merged
merged 8 commits into from
Jun 13, 2021

Conversation

pranavrajpal
Copy link
Contributor

This frees everything created in the generated initialization function so that we don't leak memory in the case of an error during initialization, as mentioned in #10586 (review).

Add decrefs to the end of the generated init function to make sure we
free everything we need to in the case of an error.
for cl in module.classes:
if cl.is_generated:
type_struct = emitter.type_struct_name(cl)
type_structs.append(type_struct)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to collect the type structs even for the not generated ones. The is_generated classes (like those created for nested functions) get initialized here, but most classes get initialized by code we generated as IR, as part of the module initialization function.

(I can't remember why we don't arrange to do that for the generated ones; obviously I didn't feel great about that fact, which is why this block of code is labeled HACK :))

Copy link
Contributor Author

@pranavrajpal pranavrajpal Jun 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be fixed by 24f5ce3.

@@ -918,7 +920,13 @@ def generate_module_def(self, emitter: Emitter, module_name: str, module: Module

emitter.emit_line('return {};'.format(module_static))
emitter.emit_lines('fail:',
'{} = NULL;'.format(module_static),
'Py_XDECREF({});'.format(module_static),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do Py_CLEAR for these, which will do an Py_XDECREF and NULL out the variable. (By virtue of being a macro that does not behave like a function...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fixed by ff3d717 and 9420cec.

'Py_XDECREF(modname);')
# the type objects returned from CPyType_FromTemplate are all new references
# so we have to decref them
for t in type_structs:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also do the finals, too. Those need to be reset to whatever the proper error value for the type is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you take a look at ea8b1b2? I added clean up for some finals but I think there are some types that we should clean up which that doesn't cover.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the right thing to do is to call out to emit_dec_ref, which knows how to decref everything: https://github.com/python/mypy/blob/master/mypyc/codegen/emit.py#L344

And then assign the result of c_undefined_value to the variable, to clear it out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that does look a lot cleaner. This should be fixed in ebe20ed.

modname might be uninitialized if PyModule_Create fails with an error,
so initialize modname to NULL at the beginning of the function so that
Py_XDECREF does nothing.
Free the type structs associated with all classes in the case of an
error, regardless of whether those classes are generated.
Use Py_CLEAR instead of using Py_XDECREF on the module object we created
and then setting it to NULL because Py_CLEAR does the same thing.
Make sure we clean up finals if we run into an error while running the
initialization code.
Use Py_CLEAR on the module name and all of the type structs to make sure
that those are set to NULL if we run into an error.
@pranavrajpal pranavrajpal requested a review from msullivan June 8, 2021 23:29
'return NULL;')
'Py_CLEAR({});'.format(module_static),
'Py_CLEAR(modname);')
# the type objects returned from CPyType_FromTemplate are all new references
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment has drifted away from the code it is describing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fixed in ff8d287.

The comment about why we have to decref and clear type structs got moved
in one of the previous commits, so move it back to the right place.
Improve the handling of final values for types other than python objects
and tagged integers by using emit_dec_ref and c_undefined_value. In
particular, this should handle tuples correctly and make sure to clear
tagged integers correctly.
@msullivan msullivan merged commit db7e335 into python:master Jun 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants