public void WriteOffViewFormat(string fileName, NativeProfilerUnit unit) { StreamWriter m_sw = new StreamWriter(fileName, false, Encoding.Default); m_sw.WriteLine(c_line, "Calls", "Level", "Function", "Module", "Time", "Type", "Warnings"); uint startLevel = unit.NestingLevel; uint index = unit.NItem; uint returnTime = unit.ReturnTime; uint maxNodeN = GetNMax(); while (index < maxNodeN && ((NativeProfilerUnit)htN[index]).ReturnTime <= returnTime) { m_sw.WriteLine(c_line, "1", (GetUnitNestingLevel(index) - startLevel).ToString(), GetUnitFunctionName(index), "0", GetUnitInclTime(index), " ", " "); index++; } WriteGibberishForOffView(m_sw); m_sw.WriteLine(); m_sw.WriteLine("STATISTICS:"); m_sw.WriteLine("Total Threads = 0"); m_sw.WriteLine("Maximum Concurrent Threads = 1"); m_sw.WriteLine("Total Function Nodes = {0}", (index - unit.NItem)); m_sw.WriteLine("Total Function Calls = {0}", (index - unit.NItem)); m_sw.WriteLine("Memory Buffer Used = 1K"); m_sw.WriteLine("Memory Buffer Allocated = 1K"); m_sw.WriteLine("Memory Buffer Reserved = 2K"); m_sw.Flush(); m_sw.Close(); }
public string GetUnitFunctionName(NativeProfilerUnit unit) { return((string)htFunctionNames[unit.FunctionAddress]); }
public NativeProfiler(Stream m_tInput, string mapFileName, bool b_checkBlockBegin) { bool needRestart = true; long streamLength = m_tInput.Length; uint nRestarts = 0; while (needRestart == true && streamLength > 0) { needRestart = false; try { NativeProfilerUnit[] htN_temp = new NativeProfilerUnit[streamLength]; htFunctionNames = new Hashtable(); htN = new NativeProfilerUnit[streamLength]; htInclTime = new uint[streamLength]; htExclTime = new uint[streamLength]; Stack stack = new Stack(8096); byte[] bArray = new byte[20]; m_tInput.Seek(0, SeekOrigin.Begin); nItems = 0; totalRuntime = 0; long n = 0; uint level = 0; uint address = 0, time = 0; uint checkValue = 0; NativeProfilerUnit unit; if (b_checkBlockBegin == true) { while (streamLength - m_tInput.Position >= 4 && checkValue != 0xbaadf00d) { m_tInput.Read(bArray, 0, 4); checkValue = BitConverter.ToUInt32(bArray, 0); if (checkValue != 0xbaadf00d) { m_tInput.Seek(-3, SeekOrigin.Current); } else { m_tInput.Read(bArray, 0, 4); engineTimeOffset = BitConverter.ToUInt32(bArray, 0); } } } while (streamLength - m_tInput.Position >= 8) { m_tInput.Read(bArray, 0, 8); address = BitConverter.ToUInt32(bArray, 0); time = BitConverter.ToUInt32(bArray, 4); if (address != 0xbaadf00d && address != 0xd00fdaab && time != 0xbaadf00d && time != 0xd00fdaab) { if ((address & 1) == 0) // if the address is even then it is a push opcode { unit = new NativeProfilerUnit(); unit.EntryTime = time; unit.FunctionAddress = address; unit.NestingLevel = level; unit.ReturnTime = 0xffffffff; htN_temp[n] = unit; stack.Push(unit); n++; level++; // Adds a reference that a key for 'address' exists in htFunctionNames. htFunctionNames[address] = null; } else if (stack.Count > 0) // if the address is odd then it is a pop opcode { unit = (NativeProfilerUnit)stack.Pop(); unit.ReturnTime = time; level--; } } else if (time == 0xbaadf00d) { if (m_tInput.Length - m_tInput.Position >= 4) { m_tInput.Seek(4, SeekOrigin.Current); } } else if (address == 0xd00fdaab || time == 0xd00fdaab) { if (time != 0xbaadf00d) { m_tInput.Seek(-3, SeekOrigin.Current); } while (streamLength - m_tInput.Position >= 4 && time != 0xbaadf00d) { m_tInput.Read(bArray, 0, 4); time = BitConverter.ToUInt32(bArray, 0); if (time != 0xbaadf00d) { m_tInput.Seek(-3, SeekOrigin.Current); } } m_tInput.Read(bArray, 0, 4); } } OpenMAPFile(mapFileName); totalRuntime = 0; // Do some simple data consistancy check // We use time, and check that the level of the next unit - level of the previous level is <= 1; uint index = 0; unit = (NativeProfilerUnit)htN_temp[index]; minimalLevel = 0xffffffff; while (unit != null) { if (unit.ReturnTime > unit.EntryTime && unit.ReturnTime != 0xffffffff && unit.EntryTime != 0xffffffff && htFunctionNames[unit.FunctionAddress] != null && (nItems == 0 || nItems != 0 && ((int)unit.NestingLevel - (int)htN[nItems - 1].NestingLevel <= 1))) { htN[nItems] = unit; unit.NItem = nItems; nItems++; if (unit.NestingLevel < minimalLevel) { minimalLevel = unit.NestingLevel; } } else { if (nItems != 0) { // If the node after the last one is not correct then destroy the last node too. htN[nItems - 1] = null; nItems--; } break; } index++; unit = (NativeProfilerUnit)htN_temp[index]; } if (minimalLevel == 0xffffffff) { minimalLevel = 0; } // The last nodes seems to be scratched sometimes. // So we ignore everything from the node after the last one until the node of level minimalLevel, // or the node which is null (if it is not already that one). NativeProfilerUnit lastNode; uint lastLevel = minimalLevel; index = nItems; do { lastNode = (NativeProfilerUnit)htN[index]; if (lastNode != null) { lastLevel = lastNode.NestingLevel; } index--; }while (lastNode != null && lastLevel > minimalLevel); if (index != nItems - 1) { lastNode = (NativeProfilerUnit)htN[index]; } unit = (NativeProfilerUnit)htN[(uint)0]; index = 0; while (unit != null && unit != lastNode) { index++; unit = (NativeProfilerUnit)htN[index]; } nItems = index; htN[nItems] = null; // Count inclusive, exclusive time for (index = 0; index < nItems; index++) { unit = GetUnit(index); uint entryTime = unit.EntryTime; uint returnTime = unit.ReturnTime; level = unit.NestingLevel; uint count = index + 1; long exclTime = (long)unit.ExecutionTime - (long)EngineTimeOffset; while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime) { if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1) { exclTime = exclTime - ((NativeProfilerUnit)htN[count]).ExecutionTime; } count++; } if (exclTime < 0) { exclTime = 0; } htExclTime[index] = (uint)exclTime; } for (index = nItems - 1; (int)index >= 0; index--) { unit = GetUnit(index); uint entryTime = unit.EntryTime; uint returnTime = unit.ReturnTime; level = unit.NestingLevel; uint count = index + 1; long inclTime = 0; while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime) { if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1) { inclTime = inclTime + htInclTime[count]; } count++; } inclTime += htExclTime[index]; htInclTime[index] = (uint)(inclTime); if (unit.NestingLevel == minimalLevel) { totalRuntime += (uint)inclTime; } } } catch (System.OutOfMemoryException) { if (nRestarts == 0) { System.Windows.Forms.MessageBox.Show("Out of memory. Will try to strip data until load of data is possible."); } needRestart = true; streamLength /= 2; nRestarts++; } catch (Exception e) { System.Windows.Forms.MessageBox.Show("Unfortunately there was an error during decoding data. Exception sent: " + e.ToString()); } } }
public string GetUnitFunctionName(NativeProfilerUnit unit) { return (string)htFunctionNames[unit.FunctionAddress]; }
public NativeProfiler(Stream m_tInput, string mapFileName, bool b_checkBlockBegin) { bool needRestart = true; long streamLength = m_tInput.Length; uint nRestarts = 0; while (needRestart == true && streamLength > 0) { needRestart = false; try { NativeProfilerUnit[] htN_temp = new NativeProfilerUnit[streamLength]; htFunctionNames = new Hashtable(); htN = new NativeProfilerUnit[streamLength]; htInclTime = new uint[streamLength]; htExclTime = new uint[streamLength]; Stack stack = new Stack(8096); byte[] bArray = new byte[20]; m_tInput.Seek(0, SeekOrigin.Begin); nItems = 0; totalRuntime = 0; long n = 0; uint level = 0; uint address = 0, time = 0; uint checkValue = 0; NativeProfilerUnit unit; if (b_checkBlockBegin == true) { while (streamLength - m_tInput.Position >= 4 && checkValue != 0xbaadf00d) { m_tInput.Read(bArray, 0, 4); checkValue = BitConverter.ToUInt32(bArray, 0); if (checkValue != 0xbaadf00d) { m_tInput.Seek(-3, SeekOrigin.Current); } else { m_tInput.Read(bArray, 0, 4); engineTimeOffset = BitConverter.ToUInt32(bArray, 0); } } } while (streamLength - m_tInput.Position >= 8) { m_tInput.Read(bArray, 0, 8); address = BitConverter.ToUInt32(bArray, 0); time = BitConverter.ToUInt32(bArray, 4); if (address != 0xbaadf00d && address != 0xd00fdaab && time != 0xbaadf00d && time != 0xd00fdaab) { if ((address & 1) == 0) // if the address is even then it is a push opcode { unit = new NativeProfilerUnit(); unit.EntryTime = time; unit.FunctionAddress = address; unit.NestingLevel = level; unit.ReturnTime = 0xffffffff; htN_temp[n] = unit; stack.Push(unit); n++; level++; // Adds a reference that a key for 'address' exists in htFunctionNames. htFunctionNames[address] = null; } else if (stack.Count > 0) // if the address is odd then it is a pop opcode { unit = (NativeProfilerUnit)stack.Pop(); unit.ReturnTime = time; level--; } } else if (time == 0xbaadf00d) { if (m_tInput.Length - m_tInput.Position >= 4) { m_tInput.Seek(4, SeekOrigin.Current); } } else if (address == 0xd00fdaab || time == 0xd00fdaab) { if (time != 0xbaadf00d) { m_tInput.Seek(-3, SeekOrigin.Current); } while (streamLength - m_tInput.Position >= 4 && time != 0xbaadf00d) { m_tInput.Read(bArray, 0, 4); time = BitConverter.ToUInt32(bArray, 0); if (time != 0xbaadf00d) { m_tInput.Seek(-3, SeekOrigin.Current); } } m_tInput.Read(bArray, 0, 4); } } OpenMAPFile(mapFileName); totalRuntime = 0; // Do some simple data consistancy check // We use time, and check that the level of the next unit - level of the previous level is <= 1; uint index = 0; unit = (NativeProfilerUnit)htN_temp[index]; minimalLevel = 0xffffffff; while (unit != null) { if (unit.ReturnTime > unit.EntryTime && unit.ReturnTime != 0xffffffff && unit.EntryTime != 0xffffffff && htFunctionNames[unit.FunctionAddress] != null && (nItems == 0 || nItems != 0 && ((int)unit.NestingLevel - (int)htN[nItems - 1].NestingLevel <= 1))) { htN[nItems] = unit; unit.NItem = nItems; nItems++; if (unit.NestingLevel < minimalLevel) minimalLevel = unit.NestingLevel; } else { if (nItems != 0) { // If the node after the last one is not correct then destroy the last node too. htN[nItems - 1] = null; nItems--; } break; } index++; unit = (NativeProfilerUnit)htN_temp[index]; } if (minimalLevel == 0xffffffff) minimalLevel = 0; // The last nodes seems to be scratched sometimes. // So we ignore everything from the node after the last one until the node of level minimalLevel, // or the node which is null (if it is not already that one). NativeProfilerUnit lastNode; uint lastLevel = minimalLevel; index = nItems; do { lastNode = (NativeProfilerUnit)htN[index]; if (lastNode != null) lastLevel = lastNode.NestingLevel; index--; } while (lastNode != null && lastLevel > minimalLevel); if (index != nItems - 1) lastNode = (NativeProfilerUnit)htN[index]; unit = (NativeProfilerUnit)htN[(uint)0]; index = 0; while (unit != null && unit != lastNode) { index++; unit = (NativeProfilerUnit)htN[index]; } nItems = index; htN[nItems] = null; // Count inclusive, exclusive time for (index = 0; index < nItems; index++) { unit = GetUnit(index); uint entryTime = unit.EntryTime; uint returnTime = unit.ReturnTime; level = unit.NestingLevel; uint count = index + 1; long exclTime = (long)unit.ExecutionTime - (long)EngineTimeOffset; while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime) { if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1) { exclTime = exclTime - ((NativeProfilerUnit)htN[count]).ExecutionTime; } count++; } if (exclTime < 0) exclTime = 0; htExclTime[index] = (uint)exclTime; } for (index = nItems - 1; (int)index >= 0; index--) { unit = GetUnit(index); uint entryTime = unit.EntryTime; uint returnTime = unit.ReturnTime; level = unit.NestingLevel; uint count = index + 1; long inclTime = 0; while (count < nItems && htN[count] != null && ((NativeProfilerUnit)htN[count]).ReturnTime < returnTime && ((NativeProfilerUnit)htN[count]).EntryTime < returnTime) { if (((NativeProfilerUnit)htN[count]).NestingLevel == level + 1) { inclTime = inclTime + htInclTime[count]; } count++; } inclTime += htExclTime[index]; htInclTime[index] = (uint)(inclTime); if (unit.NestingLevel == minimalLevel) totalRuntime += (uint)inclTime; } } catch (System.OutOfMemoryException) { if(nRestarts == 0) System.Windows.Forms.MessageBox.Show("Out of memory. Will try to strip data until load of data is possible."); needRestart = true; streamLength /= 2; nRestarts++; } catch (Exception e) { System.Windows.Forms.MessageBox.Show("Unfortunately there was an error during decoding data. Exception sent: " + e.ToString()); } } }