Frozen references

Topics: Metadata Model, PE Writer
Jun 10, 2011 at 10:35 AM

While introducing freezing for mutable references (i.e. TypeReference, FieldReference, MethodReference, etc.) boosts the performance for metadata generation scenarios, it really makes difficult using them in mutating existing metadata scenarios.

For example, consider the case when some code interns a TypeReference (accessing TypeReference.InternedKey), and then mutates a SpecializedTypeReference that has that TypeReference as its UnspecializedVersion. Now, SpecializedTypeReference will always return an invalid InternedKey.

 

Is there any easier way of mutating mutable reference and get their InternedKey always recomputed?

Note that unfreezing after mutating would not help, as you also have to unfreeze all of the references based on the reference (e.g. specialized instances).

Coordinator
Jun 10, 2011 at 2:15 PM

Freezing was introduced to cut down on bugs. I am afraid that it is never going to be easy to mutate things while also doing traversals.

I am not sure I fully understand your example. I would think that any time you mutate a specialized reference, you also have to update the unspecialized version to agree with it. But mostly I think you should not be mutating specialized references at all. Does the Rewriter base class do this? If so, that is a bug that should be fixed. Can you provide more details?

In general, it is better to construct new references than to mutate existing ones.

Jun 18, 2011 at 1:38 PM

Wouldn't this mean that I should not use mutable references at all?

Then, why would anyone use them?

I think I will try to mutate all of the definitions, then I will just update the references by rebuilding them (using classes from Immutable?).

Coordinator
Jun 18, 2011 at 3:10 PM
Edited Jun 18, 2011 at 3:11 PM

There are some scenarios where it is useful to be able to mutate a reference. For example, if you want to update an assembly to reference assembly A' instead of A, you can just rewrite the assembly and mutate every reference that points to A. You just have to be careful to first copy the assembly and then to not do anything that will freeze the references you want to mutate.

But in general, yes, avoid mutating references. Recreate them instead (one easy way to do that is to copy them). A complicating factor is the fact that reference objects can be shared. This is a useful memory optimization, but it does mean that you have to be very careful when mutating, particularly if you want to preserve the sharing.