protected bool PrevEvent(double?minTime) { var v = m_MmapView; if (m_MmapPos == MetaData.EncodedDataSizeBytes) { m_MmapPos = m_MmapPrevPos; } var pos = m_MmapPos; var inpos = pos; if (pos == 16) { return(false); } bool isV3 = MetaData.Version >= 3; EventHeader headerSkip; EventHeader.Decode(out headerSkip, v, ref pos); pos = m_MmapPos - headerSkip.BackLink; var resetPos = pos; EventHeader header; EventHeader.Decode(out header, v, ref pos); if (minTime.HasValue && minTime > header.TimeStamp) { m_MmapPos = inpos; return(false); } m_CurrentTime = header.TimeStamp; switch (header.Code) { case EventCode.HeapCreate: { HeapCreateEvent ev; HeapCreateEvent.Decode(out ev, v, ref pos); OnHeapDestroy(ev.Id); } break; case EventCode.HeapDestroy: { HeapDestroyEvent ev; HeapDestroyEvent.Decode(out ev, v, ref pos); HeapCreateEvent create_ev; long create_pos = ev.SourceEventPos + EventHeader.SizeBytes; HeapCreateEvent.Decode(out create_ev, v, ref create_pos); OnHeapCreate(create_ev.Id, create_ev.NameStringIndex); } break; case EventCode.HeapAddCore: case EventCode.HeapRemoveCore: { HeapCoreEvent ev; HeapCoreEvent.Decode(out ev, v, ref pos); if (EventCode.HeapRemoveCore == header.Code) { OnHeapAddCore(ev.Id, ev.Address, ev.Size); } else { OnHeapRemoveCore(ev.Id, ev.Address, ev.Size); } } break; case EventCode.HeapAllocate: { HeapAllocEvent ev; if (isV3) { HeapAllocEvent.DecodeV3(out ev, v, ref pos); } else { HeapAllocEvent.DecodePreV3(out ev, v, ref pos); } OnHeapFree(ev.HeapId, ev.Address, -1, 0.0); // args are bogus, we don't have that data } break; case EventCode.HeapFree: { HeapFreeEvent ev; if (isV3) { HeapFreeEvent.DecodeV3(out ev, v, ref pos); } else { HeapFreeEvent.DecodePreV3(out ev, v, ref pos); } long alloc_pos = ev.SourceEventPos; EventHeader alloc_hdr; EventHeader.Decode(out alloc_hdr, v, ref alloc_pos); HeapAllocEvent alloc_ev; if (isV3) { HeapAllocEvent.DecodeV3(out alloc_ev, v, ref alloc_pos); } else { HeapAllocEvent.DecodePreV3(out alloc_ev, v, ref alloc_pos); } OnHeapAllocate(alloc_ev.HeapId, alloc_ev.Address, alloc_ev.Size, alloc_hdr.Scope, alloc_hdr.ScopeStringIndex, alloc_hdr.BackTraceIndex, alloc_hdr.TimeStamp); } break; case EventCode.HeapReallocate: { HeapReallocEvent ev; if (isV3) { HeapReallocEvent.DecodeV3(out ev, v, ref pos); } else { HeapReallocEvent.DecodePreV3(out ev, v, ref pos); } // Restore preceding alloc which can have been either an alloc or another reallocation long old_pos = ev.SourceEventPos; EventHeader old_hdr; EventHeader.Decode(out old_hdr, v, ref old_pos); // Undo realloc allocation part OnHeapFree(ev.HeapId, ev.NewAddress, old_hdr.BackTraceIndex, old_hdr.TimeStamp); switch (old_hdr.Code) { case EventCode.HeapAllocate: { HeapAllocEvent alloc_ev; if (isV3) { HeapAllocEvent.DecodeV3(out alloc_ev, v, ref old_pos); } else { HeapAllocEvent.DecodePreV3(out alloc_ev, v, ref old_pos); } OnHeapAllocate(alloc_ev.HeapId, alloc_ev.Address, alloc_ev.Size, old_hdr.Scope, old_hdr.ScopeStringIndex, old_hdr.BackTraceIndex, old_hdr.TimeStamp); } break; case EventCode.HeapReallocate: { HeapReallocEvent realloc_ev; if (isV3) { HeapReallocEvent.DecodeV3(out realloc_ev, v, ref old_pos); } else { HeapReallocEvent.DecodePreV3(out realloc_ev, v, ref old_pos); } OnHeapAllocate(realloc_ev.HeapId, realloc_ev.NewAddress, realloc_ev.NewSize, old_hdr.Scope, old_hdr.ScopeStringIndex, old_hdr.BackTraceIndex, old_hdr.TimeStamp); } break; default: throw new IOException("Unexpected source event for reallocation " + old_hdr.Code); } } break; case EventCode.AddressAllocate: { AllocateAddressEvent ev; AllocateAddressEvent.Decode(out ev, v, ref pos); OnAddressFree(ev.Address); } break; case EventCode.AddressFree: { FreeAddressEvent ev; FreeAddressEvent.Decode(out ev, v, ref pos); long alloc_pos = ev.SourceEventPos + EventHeader.SizeBytes; AllocateAddressEvent alloc_ev; AllocateAddressEvent.Decode(out alloc_ev, v, ref alloc_pos); OnAddressAllocate(alloc_ev.Address, alloc_ev.Size, alloc_ev.NameStringIndex); break; } case EventCode.VirtualCommit: { VirtualCommitEvent ev; VirtualCommitEvent.Decode(out ev, v, ref pos); OnVirtualDecommit(ev.Address, ev.Size); } break; case EventCode.VirtualDecommit: { VirtualCommitEvent ev; VirtualCommitEvent.Decode(out ev, v, ref pos); OnVirtualCommit(ev.Address, ev.Size); } break; default: throw new IOException(String.Format("Unexpected event code {0} in stream at position {1}", header.Code, m_MmapPos)); } m_MmapPos = resetPos; return(true); }
protected bool NextEvent(double?maxTime) { var v = m_MmapView; var pos = m_MmapPos; if (pos == MetaData.EncodedDataSizeBytes) { return(false); } m_MmapPrevPos = pos; EventHeader header; EventHeader.Decode(out header, v, ref pos); bool hasHeapIds = MetaData.Version >= 3; if (maxTime.HasValue && header.TimeStamp > maxTime.Value) { return(false); } m_CurrentTime = header.TimeStamp; switch (header.Code) { case EventCode.HeapCreate: { HeapCreateEvent ev; HeapCreateEvent.Decode(out ev, v, ref pos); OnHeapCreate(ev.Id, ev.NameStringIndex); } break; case EventCode.HeapDestroy: { HeapDestroyEvent ev; HeapDestroyEvent.Decode(out ev, v, ref pos); OnHeapDestroy(ev.Id); } break; case EventCode.HeapAddCore: case EventCode.HeapRemoveCore: { HeapCoreEvent ev; HeapCoreEvent.Decode(out ev, v, ref pos); if (EventCode.HeapAddCore == header.Code) { OnHeapAddCore(ev.Id, ev.Address, ev.Size); } else { OnHeapRemoveCore(ev.Id, ev.Address, ev.Size); } } break; case EventCode.HeapAllocate: { HeapAllocEvent ev; if (hasHeapIds) { HeapAllocEvent.DecodeV3(out ev, v, ref pos); } else { HeapAllocEvent.DecodePreV3(out ev, v, ref pos); } OnHeapAllocate(ev.HeapId, ev.Address, ev.Size, header.Scope, header.ScopeStringIndex, header.BackTraceIndex, header.TimeStamp); } break; case EventCode.HeapFree: { HeapFreeEvent ev; if (hasHeapIds) { HeapFreeEvent.DecodeV3(out ev, v, ref pos); } else { HeapFreeEvent.DecodePreV3(out ev, v, ref pos); } OnHeapFree(ev.HeapId, ev.Address, header.BackTraceIndex, header.TimeStamp); } break; case EventCode.HeapReallocate: { HeapReallocEvent ev; if (hasHeapIds) { HeapReallocEvent.DecodeV3(out ev, v, ref pos); } else { HeapReallocEvent.DecodePreV3(out ev, v, ref pos); } OnHeapFree(ev.HeapId, ev.OldAddress, header.BackTraceIndex, header.TimeStamp); OnHeapAllocate(ev.HeapId, ev.NewAddress, ev.NewSize, header.Scope, header.ScopeStringIndex, header.BackTraceIndex, header.TimeStamp); } break; case EventCode.AddressAllocate: { AllocateAddressEvent ev; AllocateAddressEvent.Decode(out ev, v, ref pos); OnAddressAllocate(ev.Address, ev.Size, ev.NameStringIndex); } break; case EventCode.AddressFree: { FreeAddressEvent ev; FreeAddressEvent.Decode(out ev, v, ref pos); OnAddressFree(ev.Address); } break; case EventCode.VirtualCommit: case EventCode.VirtualDecommit: { VirtualCommitEvent ev; VirtualCommitEvent.Decode(out ev, v, ref pos); if (header.Code == EventCode.VirtualCommit) { OnVirtualCommit(ev.Address, ev.Size); } else { OnVirtualDecommit(ev.Address, ev.Size); } } break; default: throw new IOException(String.Format("Unexpected event code {0} in stream at position {1}", header.Code, m_MmapPos)); } m_MmapPos = pos; return(true); }