Moving Away From MetadataMutator to ... what?

Topics: Metadata Model, PE Writer
Feb 10, 2011 at 11:56 PM

It's been a while since I looked at my CCI-based code, but I'm diving back into it. I got the latest version of CCI, and I noticed it said that MetadataMutator is obsolete, and that MutatingVisitor and MetadataCopier should be used instead.

Problem is...I'm not sure how to replace MetadataMutator with these two classes. I tried to change my custom visitor's base class with MutatingVisitor, and I can't figure out what the correct combinations of Visit and/or Mutate methods are that I'm supposed to override. Or does MetadataCopier fit into this picture somehow.

Any advice would be greatly appreciated. MetatdataMutator still works (as the "obsolete" statement is only in a comment and not actually an Obsolete attribute), but if it's eventually going to go away I'd like to change to the new way if possible.



Feb 11, 2011 at 2:37 AM

I have just been through two weeks of tough debugging and lots of code rewriting to get rid of all of the uses of MetadataMutator in the CCI codebase. The warnings about MetadataMutator being difficult to use correctly are very accurate indeed. A major check in is coming soon. Some breaking changes as well.

The idea is to first make a copy of your assembly using MetadataCopier. Now that copy is fully mutable as well as self consistent and traversable. You just call MetadataCopier.

As for the mutator bit, you now subclass MutatingVisitor instead of MetadataMutator and provide overrides for the Mutate methods instead of the Visit methods.

Incidently, if you are going to make point mutations, such as adding in a field or a method, you may as well just use an ordinary BaseTraverser and cast down the nodes of interest to the mutable nodes they really are (after MetadataCopier has done its work). This can be more efficient than using MutatingVisitor since you are just traversing the tree rather than systematically rewriting it.

I am less than thrilled with the confusing API inconsistencies and concept overloading between visitors, traversers and mutators and I'll be looking at some API changes to make things a bit more intuitive in the next few weeks.

Feb 15, 2011 at 12:43 PM

Ah, I noticed changeset 57661 includes this change - I'll have to look at this now :)

Apr 8, 2011 at 6:58 PM

Is there a possibility of maintaining the MetadataMutator approach for performance reasons?  The MetadataCopier works extremely well, but for larger assemblies it takes a really long time to perform a copy.  For an application I have written, the total execution takes 30 seconds and the copy process alone is 29 seconds of this.  Alternatively, is there a way to efficiently create a copy that supports limited modifications that performs better?



Apr 12, 2011 at 12:23 AM

In principle there is no reason why the MetadataMutator should be noticably faster than copy+rewrite, since that is exactly what the mutator does anyway.

That said, I am unhappy with the current performance of rewriting scenarios and hope to find some time to fix that in the next month or so.

Note that one should be wary of blaming the copier for all performance problems. After all, the reader is lazy and does almost no work until the copier kicks in, so all of its efforts and GC pressure can easily be charged against the copier.

Apr 12, 2011 at 1:19 AM

Cool.  I completely understand your point about not blaming the copy process itself.  I generally am not displeased with the performance, but since I am working on an open source (free) alternative to PostSharp using these great libraries, I want the performance to be acceptable, since it affects the build time for every developer.  Let me know if you need any assistance with the performance work, if just to provide some testing feedback.

I am specifically sticking with just the Metadata libraries to avoid likely overhead of creating a code model.