The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.IlGen \ XmlILTrace

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlILTrace.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System;
  16. using System.IO;
  17. using System.Security;
  18. using System.Xml;
  19. using System.Globalization;
  20. using System.Xml.Xsl.Qil;
  21. namespace System.Xml.Xsl.IlGen
  22. {
  23.    
  24.     /// <summary>
  25.     /// Helper class that facilitates tracing of ILGen.
  26.     /// </summary>
  27.     static internal class XmlILTrace
  28.     {
  29.         private const int MAX_REWRITES = 200;
  30.        
  31.         /// <summary>
  32.         /// Check environment variable in order to determine whether to write out trace files. This really should be a
  33.         /// check of the configuration file, but System.Xml does not yet have a good tracing story.
  34.         /// </summary>
  35.         private static string dirName = null;
  36.         private static bool alreadyCheckedEnabled = false;
  37.        
  38.         /// <summary>
  39.         /// True if tracing has been enabled (environment variable set).
  40.         /// </summary>
  41.         public static bool IsEnabled {
  42.             get {
  43.                 // If environment variable has not yet been checked, do so now
  44.                 if (!alreadyCheckedEnabled) {
  45.                     try {
  46.                         dirName = Environment.GetEnvironmentVariable("XmlILTrace");
  47.                     }
  48.                     catch (SecurityException) {
  49.                         // If user does not have access to environment variables, tracing will remain disabled
  50.                     }
  51.                    
  52.                     alreadyCheckedEnabled = true;
  53.                 }
  54.                
  55.                 return (dirName != null);
  56.             }
  57.         }
  58.        
  59.         /// <summary>
  60.         /// If tracing is enabled, this method will delete the contents of "filename" in preparation for append
  61.         /// operations.
  62.         /// </summary>
  63.         public static void PrepareTraceWriter(string fileName)
  64.         {
  65.             if (!IsEnabled)
  66.                 return;
  67.            
  68.             File.Delete(dirName + "\\" + fileName);
  69.         }
  70.        
  71.         /// <summary>
  72.         /// If tracing is enabled, this method will open a TextWriter over "fileName" and return it. Otherwise,
  73.         /// null will be returned.
  74.         /// </summary>
  75.         public static TextWriter GetTraceWriter(string fileName)
  76.         {
  77.             if (!IsEnabled)
  78.                 return null;
  79.            
  80.             return new StreamWriter(dirName + "\\" + fileName, true);
  81.         }
  82.        
  83.         /// <summary>
  84.         /// Serialize Qil tree to "fileName", in the directory identified by "dirName".
  85.         /// </summary>
  86.         public static void WriteQil(QilExpression qil, string fileName)
  87.         {
  88.             if (!IsEnabled)
  89.                 return;
  90.            
  91.             XmlWriter w = XmlWriter.Create(dirName + "\\" + fileName);
  92.             try {
  93.                 WriteQil(qil, w);
  94.             }
  95.             finally {
  96.                 w.Close();
  97.             }
  98.         }
  99.        
  100.         /// <summary>
  101.         /// Trace ILGen optimizations and log them to "fileName".
  102.         /// </summary>
  103.         public static void TraceOptimizations(QilExpression qil, string fileName)
  104.         {
  105.             if (!IsEnabled)
  106.                 return;
  107.            
  108.             XmlWriter w = XmlWriter.Create(dirName + "\\" + fileName);
  109.            
  110.             w.WriteStartDocument();
  111.             w.WriteProcessingInstruction("xml-stylesheet", "href='qilo.xslt' type='text/xsl'");
  112.             w.WriteStartElement("QilOptimizer");
  113.             w.WriteAttributeString("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture));
  114.             WriteQilRewrite(qil, w, null);
  115.            
  116.             try {
  117.                 // Then, rewrite the graph until "done" or some max value is reached.
  118.                 for (int i = 1; i < MAX_REWRITES; i++) {
  119.                     QilExpression qilTemp = (QilExpression)(new QilCloneVisitor(qil.Factory).Clone(qil));
  120.                    
  121.                     XmlILOptimizerVisitor visitor = new XmlILOptimizerVisitor(qilTemp, !qilTemp.IsDebug);
  122.                     visitor.Threshold = i;
  123.                     qilTemp = visitor.Optimize();
  124.                    
  125.                     // In debug code, ensure that QIL after N steps is correct
  126.                     QilValidationVisitor.Validate(qilTemp);
  127.                    
  128.                     // Trace the rewrite
  129.                     WriteQilRewrite(qilTemp, w, OptimizationToString(visitor.LastReplacement));
  130.                    
  131.                     if (visitor.ReplacementCount < i)
  132.                         break;
  133.                 }
  134.             }
  135.             catch (Exception e) {
  136.                 if (!XmlException.IsCatchableException(e)) {
  137.                     throw;
  138.                 }
  139.                 w.WriteElementString("Exception", null, e.ToString());
  140.                 throw;
  141.             }
  142.             finally {
  143.                 w.WriteEndElement();
  144.                 w.WriteEndDocument();
  145.                 w.Flush();
  146.                 w.Close();
  147.             }
  148.         }
  149.        
  150.         /// <summary>
  151.         /// Serialize Qil tree to writer "w".
  152.         /// </summary>
  153.         private static void WriteQil(QilExpression qil, XmlWriter w)
  154.         {
  155.             QilXmlWriter qw = new QilXmlWriter(w);
  156.             qw.ToXml(qil);
  157.         }
  158.        
  159.         /// <summary>
  160.         /// Serialize rewritten Qil tree to writer "w".
  161.         /// </summary>
  162.         private static void WriteQilRewrite(QilExpression qil, XmlWriter w, string rewriteName)
  163.         {
  164.             w.WriteStartElement("Diff");
  165.             if (rewriteName != null)
  166.                 w.WriteAttributeString("rewrite", rewriteName);
  167.             WriteQil(qil, w);
  168.             w.WriteEndElement();
  169.         }
  170.        
  171.         /// <summary>
  172.         /// Get friendly string description of an ILGen optimization.
  173.         /// </summary>
  174.         private static string OptimizationToString(int opt)
  175.         {
  176.             string s = Enum.GetName(typeof(XmlILOptimization), opt);
  177.             if (s.StartsWith("Introduce", StringComparison.Ordinal)) {
  178.                 return s.Substring(9) + " introduction";
  179.             }
  180.             else if (s.StartsWith("Eliminate", StringComparison.Ordinal)) {
  181.                 return s.Substring(9) + " elimination";
  182.             }
  183.             else if (s.StartsWith("Commute", StringComparison.Ordinal)) {
  184.                 return s.Substring(7) + " commutation";
  185.             }
  186.             else if (s.StartsWith("Fold", StringComparison.Ordinal)) {
  187.                 return s.Substring(4) + " folding";
  188.             }
  189.             else if (s.StartsWith("Misc", StringComparison.Ordinal)) {
  190.                 return s.Substring(4);
  191.             }
  192.             return s;
  193.         }
  194.     }
  195. }

Developer Fusion