private void ParseObjectHeader(StartIndices startIndices, MemorySection[] heap, ulong originalHeapAddress, out ulong typeInfoAddress, out int indexOfObject, out bool wasAlreadyCrawled, List <PackedManagedObject> outManagedObjects) { BytesAndOffset bo = heap.Find(originalHeapAddress, _virtualMachineInformation); UInt64 pointer1 = bo.ReadPointer(); BytesAndOffset pointer2 = bo.NextPointer(); if (HasMarkBit(pointer1) == 0) { TypeDescription typeDescription = GetTypeDescription(heap, pointer1); wasAlreadyCrawled = false; indexOfObject = outManagedObjects.Count + startIndices.OfFirstManagedObject; typeInfoAddress = typeDescription.typeInfoAddress; int size = SizeOfObjectInBytes(typeDescription, bo, heap, originalHeapAddress); outManagedObjects.Add(new PackedManagedObject() { address = originalHeapAddress, size = size, typeIndex = typeDescription.typeIndex }); //okay, we gathered all information, now lets set the mark bit, and store the index for this object in the 2nd pointer of the header, which is rarely used. bo.WritePointer(pointer1 | 1); pointer2.WritePointer((ulong)indexOfObject); return; } //give typeinfo address back without the markbit typeInfoAddress = ClearMarkBit(pointer1); wasAlreadyCrawled = true; //read the index for this object that we stored in the 2ndpointer field of the header indexOfObject = (int)pointer2.ReadPointer(); }
private TypeDescription RestoreObjectHeader(MemorySection[] heaps, ulong address, int managedObjectIndex) { BytesAndOffset bo = heaps.Find(address, _virtualMachineInformation); UInt64 mask = this._virtualMachineInformation.pointerSize == 8 ? System.UInt64.MaxValue - 1 : System.UInt32.MaxValue - 1; UInt64 pointer = bo.ReadPointer(); UInt64 typeInfoAddress = pointer & mask; bo.WritePointer(typeInfoAddress); UInt64 restoreValue = 0; _pointer2Backups.TryGetValue(managedObjectIndex, out restoreValue); bo.NextPointer().WritePointer(restoreValue); return(GetTypeDescription(heaps, typeInfoAddress)); }