Exemple #1
0
        private IEnumerable <Connection> AddManagedToNativeConnectionsAndRestoreObjectHeaders(PackedMemorySnapshot packedMemorySnapshot, StartIndices startIndices, PackedCrawlerData packedCrawlerData)
        {
            if (packedMemorySnapshot.typeDescriptions.Length == 0)
            {
                yield break;
            }

            var unityEngineObjectTypeDescription = packedMemorySnapshot.typeDescriptions.First(td => td.name == "UnityEngine.Object");

            bool unityEngineObjectHasInstanceIDField = unityEngineObjectTypeDescription.fields.Any(f => f.name == "m_InstanceID");
            int  instanceIDOffset = -1;

            if (unityEngineObjectHasInstanceIDField)
            {
                instanceIDOffset = unityEngineObjectTypeDescription.fields.Single(f => f.name == "m_InstanceID").offset;
            }

#if UNITY_5_4_OR_NEWER
            var cachedPtrOffset = unityEngineObjectTypeDescription.fields.Single(f => f.name == "m_CachedPtr").offset;
#endif

            for (int i = 0; i != packedCrawlerData.managedObjects.Length; i++)
            {
                var managedObjectIndex = i + startIndices.OfFirstManagedObject;
                var address            = packedCrawlerData.managedObjects[i].address;

                var typeInfoAddress = RestoreObjectHeader(packedMemorySnapshot.managedHeapSections, address, managedObjectIndex);

                if (!DerivesFrom(packedMemorySnapshot.typeDescriptions, _typeInfoToTypeDescription[typeInfoAddress].typeIndex, unityEngineObjectTypeDescription.typeIndex))
                {
                    continue;
                }

                int indexOfNativeObject = -1;
                if (unityEngineObjectHasInstanceIDField)
                {
                    var instanceID = packedMemorySnapshot.managedHeapSections.Find(address + (UInt64)instanceIDOffset, packedMemorySnapshot.virtualMachineInformation).ReadInt32();
                    indexOfNativeObject = Array.FindIndex(packedMemorySnapshot.nativeObjects, no => no.instanceId == instanceID);
                }
#if UNITY_5_4_OR_NEWER // Since Unity 5.4, UnityEngine.Object no longer stores instance id inside when running in the player. Use cached ptr instead to find the index of native object
                else
                {
                    // If you get a compilation error on the following 2 lines, update to Unity 5.4b14.
                    var cachedPtr = packedMemorySnapshot.managedHeapSections.Find(address + (UInt64)cachedPtrOffset, packedMemorySnapshot.virtualMachineInformation).ReadPointer();
                    indexOfNativeObject = Array.FindIndex(packedMemorySnapshot.nativeObjects, no => (ulong)no.nativeObjectAddress == cachedPtr);
                }
#endif

                if (indexOfNativeObject != -1)
                {
                    yield return new Connection {
                               @from = managedObjectIndex, to = indexOfNativeObject + startIndices.OfFirstNativeObject
                    }
                }
                ;
            }
        }