protected override void OnBeforeBuildTree() { // This method builds a lookup table of objects that are // references by the m_target field of a System.Delegate object. var reader = new MemoryReader(m_Snapshot); var systemDelegate = m_Snapshot.managedTypes[m_Snapshot.coreTypes.systemDelegate]; PackedManagedField field; if (!systemDelegate.TryGetField("m_target", out field)) { return; } // Build a table that contains indices of all objects that are the "Target" of a delegate for (int n = 0, nend = m_Snapshot.managedObjects.Length; n < nend; ++n) { if (window.isClosing) // the window is closing { break; } var obj = m_Snapshot.managedObjects[n]; if (obj.address == 0) { continue; } // Is this a System.Delegate? var type = m_Snapshot.managedTypes[obj.managedTypesArrayIndex]; if (!m_Snapshot.IsSubclassOf(type, m_Snapshot.coreTypes.systemDelegate)) { continue; } // Read the delegate m_target pointer var pointer = reader.ReadPointer(obj.address + (uint)field.offset); if (pointer == 0) { continue; } // Try to find the managed object where m_target points to var target = m_Snapshot.FindManagedObjectOfAddress(pointer); if (target < 0) { continue; } // We found a managed object that is referenced by a System.Delegate m_delegateObjectTable[target] = 1; } }
void TryConnectNativeObject(ref PackedManagedObject managedObj) { if (managedObj.nativeObjectsArrayIndex >= 0) { return; // connected already } // If it's not derived from UnityEngine.Object, it does not have the m_CachedPtr field and we can skip it var type = m_Snapshot.managedTypes[managedObj.managedTypesArrayIndex]; if (type.isValueType || type.isArray) { return; } // Only types derived from UnityEngine.Object have the m_cachePtr field if (!type.isUnityEngineObject) { return; } BeginProfilerSample("ReadPointer"); // Read the m_cachePtr value var nativeObjectAddress = m_MemoryReader.ReadPointer(managedObj.address + (uint)m_CachedPtr.offset); EndProfilerSample(); if (nativeObjectAddress == 0) { return; } // Try to find the corresponding native object BeginProfilerSample("FindNativeObjectOfAddress"); var nativeObjectArrayIndex = m_Snapshot.FindNativeObjectOfAddress(nativeObjectAddress); EndProfilerSample(); if (nativeObjectArrayIndex < 0) { return; } // Connect ManagedObject <> NativeObject managedObj.nativeObjectsArrayIndex = nativeObjectArrayIndex; m_Snapshot.nativeObjects[managedObj.nativeObjectsArrayIndex].managedObjectsArrayIndex = managedObj.managedObjectsArrayIndex; // Connect the ManagedType <> NativeType m_Snapshot.managedTypes[managedObj.managedTypesArrayIndex].nativeTypeArrayIndex = m_Snapshot.nativeObjects[managedObj.nativeObjectsArrayIndex].nativeTypesArrayIndex; m_Snapshot.nativeTypes[m_Snapshot.nativeObjects[managedObj.nativeObjectsArrayIndex].nativeTypesArrayIndex].managedTypeArrayIndex = m_Snapshot.managedTypes[managedObj.managedTypesArrayIndex].managedTypesArrayIndex; BeginProfilerSample("AddConnection"); // Add a Connection from ManagedObject to NativeObject (m_CachePtr) m_Snapshot.AddConnection(PackedConnection.Kind.Managed, managedObj.managedObjectsArrayIndex, PackedConnection.Kind.Native, managedObj.nativeObjectsArrayIndex); EndProfilerSample(); }