void ShowSymbolInfo(SymbolInfo info) { dataGridViewSymbolInfo.Rows.Clear(); if (!info.HasChildren) { return; } if (bUpdateStack && (UndoStack.Count == 0 || info.m_name != UndoStack.Peek())) { RedoStack.Clear(); UndoStack.Push(info.m_name); } long cacheLineSize = (long)GetCacheLineSize(); long prevCacheBoundaryOffset = m_prefetchStartOffset; if (prevCacheBoundaryOffset > (long)info.m_size) { prevCacheBoundaryOffset = (long)info.m_size; } long numCacheLines = 0; InsertCachelineBoundaryRowsDelegate InsertCachelineBoundaryRows = (nextOffset) => { while (nextOffset - prevCacheBoundaryOffset >= cacheLineSize) { numCacheLines = numCacheLines + 1; long cacheLineOffset = numCacheLines * cacheLineSize + m_prefetchStartOffset; string[] boundaryRow = { "Cacheline boundary", cacheLineOffset.ToString(), "" }; dataGridViewSymbolInfo.Rows.Add(boundaryRow); prevCacheBoundaryOffset = cacheLineOffset; } }; foreach (SymbolInfo child in info.m_children) { if (child.m_padding > 0) { long paddingOffset = child.m_offset - child.m_padding; InsertCachelineBoundaryRows(paddingOffset); string[] paddingRow = { "*Padding*", paddingOffset.ToString(), child.m_padding.ToString() }; dataGridViewSymbolInfo.Rows.Add(paddingRow); } InsertCachelineBoundaryRows(child.m_offset); string[] row = { child.m_name, child.m_offset.ToString(), child.m_size.ToString() }; dataGridViewSymbolInfo.Rows.Add(row); dataGridViewSymbolInfo.Rows[dataGridViewSymbolInfo.Rows.Count - 1].Tag = child; if (child.m_typeName != null && child.m_typeName.Length != 0) { dataGridViewSymbolInfo.Rows[dataGridViewSymbolInfo.Rows.Count - 1].Cells[0].ToolTipText = child.m_typeName; } } // Final structure padding. if (info.m_padding > 0) { long paddingOffset = (long)info.m_size - info.m_padding; string[] paddingRow = { "*Padding*", paddingOffset.ToString(), info.m_padding.ToString() }; dataGridViewSymbolInfo.Rows.Add(paddingRow); } }
public CruncherReport(string PDBFile, string CSVFile) { m_CruncherData = new CruncherData(); string result = m_CruncherData.loadDataFromPdb(PDBFile); if (result != null) { System.Console.WriteLine(result); return; } List <Tuple <string, ulong, ulong> > SymbolsToValidate = new List <Tuple <string, ulong, ulong> >(); TextFieldParser parser = new TextFieldParser(CSVFile); parser.Delimiters = new String[] { "," }; while (true) { string[] elements = parser.ReadFields(); if (elements == null) { break; } SymbolsToValidate.Add(new Tuple <string, ulong, ulong>(elements[0], Convert.ToUInt64(elements[1]), Convert.ToUInt64(elements[2]))); } foreach (Tuple <string, ulong, ulong> SymbolToValidate in SymbolsToValidate) { SymbolInfo Info = m_CruncherData.FindSymbolInfo(SymbolToValidate.Item1); if (Info == null) { System.Console.WriteLine("ERROR: Unable to find symbol '" + SymbolToValidate.Item1 + "' in PDB"); } else { if (Info.m_size > SymbolToValidate.Item2) { string Larger = "WARNING: Symbol '" + SymbolToValidate.Item1 + "'was expected to be " + SymbolToValidate.Item2 + " bytes with " + SymbolToValidate.Item3 + " bytes of padding, however it is " + Info.m_size + " bytes with " + Info.m_padding + " bytes of padding. Inspect symbol to ensure no unneeded size regressions have occurred and update expected symbol size csv as needed."; System.Console.WriteLine(Larger); } else if (Info.m_size < SymbolToValidate.Item2) { string Smaller = "Symbol '" + SymbolToValidate.Item1 + "'was expected to be " + SymbolToValidate.Item2 + " bytes with " + SymbolToValidate.Item3 + " bytes of padding, however it is " + Info.m_size + " bytes with " + Info.m_padding + " bytes of padding. Consider updating symbol size csv as to maintain size savings."; System.Console.WriteLine(Smaller); } } } }