[IronPython] Code generation questions

Dino Viehland dinov at exchange.microsoft.com
Fri Feb 29 10:44:24 PST 2008

In the code you have below we should generate everything as collectible code.  As long as you hold onto the delegate to Run you'll keep all of the code alive.  Calling it after the engine is disposed will result in undefined behavior.  And in this case Run will be generated as a dynamic method (as well as __init__ and DoWork).  Run will have a reference to it's module (how it finds Foo) which is the reason why all of this will stay alive until you drop the reference to Run.

Let me describe our general code collection strategy.  There are two points where we will generate non-collectible code.  The first is when you're inheriting from a .NET type such as:

class foo(object): pass

In this case we'll generate a subclass of object which overrides virtual methods and holds onto a python type object to track it's real type.  We'll share the generated type between all types that inherit from object (adding __slots__ to a type definition causes more types to get generated).  In your sample because you're using old-style classes no code is generated.

The 2nd place where we generate uncollectible code is for modules.  So if you have foo.py on disk and you do import foo we'll generate a type for the foo module.  This is really just a performance optimization and can be turned off in both 1.0 and 2.0 (-X:GenerateAsSnippets command line option in 1.0 and most of 2.0, -X:TupleBasedOptimizedScopes in the latest 2.0 builds).  This allows the modules to directly access static fields instead of having various values in dictionaries.

If you're just sending some code off to a PythonEngine to be compiled though we'll use DynamicMethods.  Those methods will be collected when the last reference to them goes away.

2.0 uses the same strategy here as 1.0 but when we compile modules in a collectibe way they run much faster than in 1.0.

-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Masters, Christopher
Sent: Friday, February 29, 2008 7:22 AM
To: 'users at lists.ironpython.com'
Subject: [IronPython] Code generation questions


Sorry if this is documented somewhere but can anyone help me with the following?

If I (in 1.1.1) Execute() a string with code that defines some classes/defs methods, how long does the code generated last? For instance if I had the following script:

class Foo:
        def __init__(self):
                # ...
        def DoWork(self):
                print "Doing work"

def Run():

And I hosted a runtime and executed this via:

using (PythonEngine pe = new PythonEngine())
        IronPython.Runtime.Calls.Function0 run;
        run = (IronPython.Runtime.Calls.Function0)pe.Globals["Run"];

Is Run emitted as a DynamicMethod? What happens to Foo? Is it a generated as a CLR type? In which case does it hang around forever?

What if I stored the Function0 reference and executed it later (after the PythonEngine is disposed)? Does the Foo type that Run instantiates still exist?

Does anything related to this change in 2.0?



Please access the attached hyperlink for an important electronic communications disclaimer:


Users mailing list
Users at lists.ironpython.com

More information about the Users mailing list