//-------------------------------------------------------------------------- // Parse the XML header of the file to work out the format. void ParseXMLHeader(string xml) { XmlDocument xDoc = new XmlDocument(); xDoc.LoadXml(xml); // Parse header XmlNodeList header = xDoc.GetElementsByTagName("Header"); foreach (XmlNode n in header[0]) { if (n.Name == "Title") mHeader.title = n.InnerXml; else if (n.Name == "Version") mHeader.version = n.InnerXml; else if (n.Name == "Description") mHeader.description = n.InnerXml; else if (n.Name == "Platform") mHeader.platform = n.InnerXml; else if (n.Name == "Configuration") mHeader.configuration = n.InnerXml; else if (n.Name == "Timestamp") mHeader.timestamp = n.InnerXml; } // Parse data fields mHeader.mAddressIndex = -1; mHeader.mCategoryIndex = -1; mHeader.mAllocSizeIndex = -1; mHeader.mAlignmentIndex = -1; mHeader.mStackTraceIndex = -1; mHeader.mNumberIndex = -1; // mHeader.mTemporaryIndex = -1; mHeader.mNameIndex = -1; XmlNodeList dataFields = xDoc.GetElementsByTagName("DataFields"); int i =0; foreach (XmlNode n in dataFields[0]) { foreach (XmlNode m in n) { if (m.Name == "Name") { string name = m.InnerXml; mLog.AddFieldName(name); if (name == "Address") mHeader.mAddressIndex = i; else if (name == "Alignment") mHeader.mAlignmentIndex = i; else if (name == "Category") mHeader.mCategoryIndex = i; else if (name == "AllocSize") mHeader.mAllocSizeIndex = i; else if (name == "Name") mHeader.mNameIndex = i; else if (name == "StackTrace") mHeader.mStackTraceIndex = i; else if (name == "Number") mHeader.mNumberIndex = i; } } i++; } // read in allocators and their ranges XmlNodeList allocators = xDoc.GetElementsByTagName("HeapRanges"); if (allocators.Count != 0) { foreach (XmlNode n in allocators[0]) { if (n.Name == "Heap") { LogEntryAllocators entry = new LogEntryAllocators(); string tempUsedToConverToInt; foreach (XmlNode m in n) { if (m.Name == "Name") { entry.mName = m.InnerXml; } else if (m.Name == "Start") { if (m.InnerText != string.Empty) { tempUsedToConverToInt = m.InnerText.Replace("0x",""); entry.mStartAddress = UInt32.Parse(tempUsedToConverToInt,System.Globalization.NumberStyles.HexNumber); } } else if (m.Name == "End") { if(m.InnerText != string.Empty) { tempUsedToConverToInt = m.InnerText.Replace("0x",""); entry.mEndAddress = UInt32.Parse(tempUsedToConverToInt,System.Globalization.NumberStyles.HexNumber); } } } mLog.AddAllocatorEntry(entry); } } } // read in categories names: XmlNodeList categories = xDoc.GetElementsByTagName("Categories"); if (categories.Count != 0) { foreach (XmlNode n in categories[0]) { if (n.Name == "Name") { string catname = n.InnerXml; mLog.AddCategory(catname); } } } }
// Binary load public bool Load(string filename) { FileStream binFile = new FileStream(filename, FileMode.Open, FileAccess.Read); BinaryReader reader = new BinaryReader(binFile); int size = reader.ReadByte(); string ver = ReadBinString(ref reader, size); if (ver != BinaryHeaderVersionString) return false; // bail ; size = reader.ReadByte(); mFormat = ReadBinString(ref reader, size); if (mFormat != "MetricsMemoryLog") return false; // // Read in string table. // stringTable.Clear(); // int numberStrings = reader.ReadInt32(); // for (int i = 0; i < numberStrings; i++) // { // stringTable.AddUnique( reader.ReadString() ); // } // Read in categories categories.Clear(); categories.Add("N/A"); backupCategories.Clear(); backupCategories.Add("N/A"); cachedCategoryIndex = 0; // Read if there are callstacks byte callstackCode = reader.ReadByte(); bool haveCallstack = callstackCode == 8; // Read total budget uint totalBudget = reader.ReadUInt32(); // Read in log entries log.Clear(); UInt32 addrLow = uint.MaxValue; UInt32 addrHigh = uint.MinValue; UInt32 logEntries = reader.ReadUInt32(); // if (logEntries == 0) logEntries = uint.MaxValue; UInt32 lastFrameIdx = uint.MaxValue; uint currCount = 0; for (UInt32 i = 0;; i++) { LogEntry logentry = new LogEntry(); try { logentry.type = reader.ReadChar(); // logentry.category = (Byte)(1); // reading allocation address and size if (logentry.type == 'A' || logentry.type == 'F') { logentry.address = reader.ReadUInt32(); logentry.allocSize = reader.ReadUInt32(); addrLow = Math.Min(addrLow, logentry.address); addrHigh = Math.Max(addrHigh, logentry.address + logentry.allocSize); } // reading tag if (logentry.type == 'A' || logentry.type == 'L') { int tagsize = reader.ReadChar(); if (tagsize > 0) { string tag = ReadBinString(ref reader, tagsize); // System.Diagnostics.Debug.Assert(false); logentry.nameString = AddString(tag.Trim()); } else logentry.nameString = AddString("NoTag"); } // reading category if (logentry.type == 'A') { // sbyte catIndex = (sbyte)reader.ReadByte(); // if(catIndex >= 0) // { // so category is already in table // logentry.category = (byte)catIndex; // } // else // { // this is a new category. Add it to the table int catSize = reader.ReadChar(); string cat = ReadBinString(ref reader, catSize); logentry.category = AddCategory(cat.Trim()); // } } // reading frame swap. This serves as time counter if (logentry.type == 'S') { if (i != lastFrameIdx + 1) { logentry.nameString = AddString("FRAME"); lastFrameIdx = i; } else { lastFrameIdx = i; continue; } } if (logentry.type == 'F') logentry.nameString = AddString("FREE"); if (logentry.type != 'A' && logentry.type != 'F' && logentry.type != 'L' && logentry.type != 'S') System.Diagnostics.Debug.Assert(false, "Wrong Entry Type!"); /* logentry.stackTraceString = -1; if ((logentry.type == 'A' || logentry.type == 'F') && haveCallstack) { uint stackdepth = reader.ReadByte(); string stacktrace = ""; for (int j = 0; j < stackdepth; j++) { uint address = reader.ReadUInt32(); string addstr = System.Convert.ToString(address); stacktrace += addstr; stacktrace += ","; } logentry.stackTraceString = AddString(stacktrace); } */ } catch(System.IO.EndOfStreamException) { logEntries = currCount; System.Diagnostics.Debug.Print("End of File reached\n"); break; } logentry.index = currCount++; log.Add(logentry); } reader.Close(); binFile.Close(); // add a default allocator LogEntryAllocators entry = new LogEntryAllocators(); entry.mName = "DefaultAlloc"; entry.mStartAddress = addrLow; entry.mEndAddress = addrHigh; // +totalBudget; AddAllocatorEntry(entry); return true; }
public void AddAllocatorEntry(LogEntryAllocators entry) { mAllocators.Add(entry); }
// Binary load public bool Load(string filename) { FileStream binFile = new FileStream(filename, FileMode.Open, FileAccess.Read); BinaryReader reader = new BinaryReader(binFile); int size = reader.ReadByte(); countReadBytes++; string ver = ReadBinString(ref reader, size); if (ver != BinaryHeaderVersionString) return false; // bail ; size = reader.ReadByte(); countReadBytes++; mFormat = ReadBinString(ref reader, size); if (mFormat != "MetricsMemoryLog") return false; // // Read in string table. // stringTable.Clear(); // int numberStrings = reader.ReadInt32(); // for (int i = 0; i < numberStrings; i++) // { // stringTable.AddUnique( reader.ReadString() ); // } // Read in categories categories.Clear(); categories.Add("N/A"); backupCategories.Clear(); // int numberCategories = 3; // reader.ReadByte(); // assuming # of categories < 511 cachedCategoryIndex = 0; // for (int i = 0, e = numberCategories; i < e; i++) { // AddCategory( ReadBinString(ref reader) ); AddCategory("Default"); // AddCategory("Physics"); // AddCategory("Animation"); } // Read if there are callstacks byte callstackCode = reader.ReadByte(); countReadBytes++; bool haveCallstack = callstackCode == 8; // Read total budget uint totalBudget = reader.ReadUInt32(); countReadBytes += 4; // Read in log entries log.Clear(); UInt32 addrLow = uint.MaxValue; UInt32 addrHigh = uint.MinValue; UInt32 logEntries = reader.ReadUInt32(); countReadBytes += 4; if (logEntries == 0) logEntries = uint.MaxValue - 1; UInt32 lastFrameIdx = uint.MaxValue - 1; for (UInt32 i = 0; i < logEntries; i++) { char testread = '0'; try{ testread = reader.ReadChar(); countReadBytes++; } catch(System.IO.EndOfStreamException) { System.Diagnostics.Debug.Print("End of File reached\n"); break; } LogEntry logentry = new LogEntry(); logentry.type = testread; // logentry.category = (Byte)(1); if (logentry.type == 'A' || logentry.type == 'F') { logentry.address = reader.ReadUInt32(); countReadBytes +=4; logentry.allocSize = reader.ReadUInt32(); countReadBytes += 4; addrLow = Math.Min(addrLow, logentry.address); addrHigh = Math.Max(addrHigh, logentry.address + logentry.allocSize); } if (logentry.type == 'A' || logentry.type == 'L') { int tagsize = reader.ReadChar(); countReadBytes++; if(tagsize > 0) { string tag = ReadBinString(ref reader, tagsize); // System.Diagnostics.Debug.Assert(false); logentry.nameString = AddString(tag.Trim()); // if (logentry.type == 'L') // System.Diagnostics.Debug.Print("{0}", tag); } else logentry.nameString = AddString("NoTag"); } else if(logentry.type == 'S') { if (i != lastFrameIdx + 1) { logentry.nameString = AddString("FRAME"); lastFrameIdx = i; } else { lastFrameIdx = i; continue; } } else if (logentry.type == 'F') logentry.nameString = AddString("FREE"); else { System.Diagnostics.Debug.Assert(false, "Wrong Entry Type!"); } logentry.stackTraceString = -1; if ((logentry.type == 'A' || logentry.type == 'F') && haveCallstack) { uint stackdepth = reader.ReadByte(); countReadBytes++; string stacktrace = ""; for (int j = 0; j < stackdepth; j++) { uint address = reader.ReadUInt32(); countReadBytes += 4; string addstr = System.Convert.ToString(address); stacktrace += addstr; stacktrace += ","; } logentry.stackTraceString = AddString(stacktrace); } logentry.number = (uint)i; log.Add(logentry); } reader.Close(); binFile.Close(); // add a default allocator LogEntryAllocators entry = new LogEntryAllocators(); entry.mName = "DefaultAlloc"; entry.mStartAddress = addrLow; entry.mEndAddress = addrHigh; // +totalBudget; AddAllocatorEntry(entry); return true; }