From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/Profiler/ObjectMemoryProfiler.cpp | 245 ++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 Runtime/Profiler/ObjectMemoryProfiler.cpp (limited to 'Runtime/Profiler/ObjectMemoryProfiler.cpp') diff --git a/Runtime/Profiler/ObjectMemoryProfiler.cpp b/Runtime/Profiler/ObjectMemoryProfiler.cpp new file mode 100644 index 0000000..31350c8 --- /dev/null +++ b/Runtime/Profiler/ObjectMemoryProfiler.cpp @@ -0,0 +1,245 @@ +#include "UnityPrefix.h" +#include "ObjectMemoryProfiler.h" +#include "MemoryProfiler.h" +#include "SerializationUtility.h" +#include "Runtime/Misc/GarbageCollectSharedAssets.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Misc/SystemInfo.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "ExtractLoadedObjectInfo.h" + +#if ENABLE_MEM_PROFILER + +#if UNITY_EDITOR +#include "Editor/Src/Prefabs/Prefab.h" +#endif + +namespace ObjectMemoryProfiler +{ + +#if ENABLE_MEM_PROFILER && ENABLE_PLAYERCONNECTION +#define USE_MONO_LIVENESS (ENABLE_MONO && !UNITY_NACL) +#endif + + +typedef std::vector ObjectList; +static const UInt32 OBJECT_MEMORY_STREAM_VERSION = 0x00000002; +static const UInt32 OBJECT_MEMORY_STREAM_TAIL = 0xAFAFAFAF; + + +#if UNITY_EDITOR +struct MonoObjectMemoryInfo +{ + int instanceId; + UInt32 memorySize; + int count; + int reason; + ScriptingStringPtr name; + ScriptingStringPtr className; +}; +#endif + +static void Serialize(dynamic_array& stream, const char* customAreaName, const char* objectName, size_t memorySize) +{ + stream.push_back(0); + stream.push_back(memorySize); + stream.push_back(0); + stream.push_back(kNotApplicable); + WriteString(stream, objectName); + WriteString(stream, customAreaName); +} + +static void Serialize(dynamic_array& stream, const char* objectName, int count ) +{ + stream.push_back(0); + stream.push_back(0); + stream.push_back(count); + stream.push_back(kNotApplicable); + WriteString(stream, objectName); + WriteString(stream, ""); +} + +static void Serialize(dynamic_array& stream, Object* object, int count ) +{ + const char* objectName = object->GetName(); + const std::string& className = object->GetClassName(); + + stream.push_back(object->GetInstanceID()); + stream.push_back(object->GetRuntimeMemorySize()); + stream.push_back(count); + stream.push_back(GetLoadedObjectReason(object)); + if(object->GetClassID() == ClassID (MonoBehaviour)) + WriteString(stream, ((MonoBehaviour*)(object))->GetScriptFullClassName().c_str()); +#if UNITY_EDITOR + else if(object->GetClassID() == ClassID (Prefab)) + WriteString(stream, ((Prefab*)(object))->GetRootGameObject()->GetName()); +#endif + else + WriteString(stream, objectName); + WriteString(stream, className.c_str()); +} + +static void SerializeHeader(dynamic_array& stream) +{ + stream.push_back(UNITY_LITTLE_ENDIAN); + int version = OBJECT_MEMORY_STREAM_VERSION; +#if ENABLE_STACKS_ON_ALL_ALLOCS + version += 0x10000000; +#endif + stream.push_back(version); +} + +void TakeMemorySnapshot(dynamic_array& stream) +{ + dynamic_array loadedObjects; + dynamic_array additionalCategories; + dynamic_array indexCounts; + dynamic_array referencedObjectIndices; + + CalculateAllObjectReferences (loadedObjects, additionalCategories, indexCounts, referencedObjectIndices); + + // MemoryProfiler Roots + MemoryProfiler::RootAllocationInfos rootInfos (kMemProfiler); + GetMemoryProfiler ()->GetRootAllocationInfos(rootInfos); + + // loaded objects contain all loaded game objects + // this is followed by additional strings that has references as well + // indexCounts contain the count for each of the previous object references + // the indices into the object array for the references + + SerializeHeader(stream); + + // serialize the referenceIndices + stream.push_back(referencedObjectIndices.size()); + WriteIntArray(stream, (int*)&referencedObjectIndices[0],referencedObjectIndices.size()); + + // serialize loaded objects followed by additionalCats + int totalObjects = loadedObjects.size() + additionalCategories.size() + rootInfos.size() + 1 + #if ENABLE_MONO + + 2 + #endif + ; + stream.push_back(totalObjects); + + for(int i = 0 ; i < loadedObjects.size() ; i++) + { + Serialize(stream, loadedObjects[i], indexCounts[i]); + } + + for(int i=0;i (reference_array, 0), numberOfReferences); + + // objectCount + int numberOfObjects = *current_offset++; + MonoClass* klass = GetMonoManager().GetMonoClass ("ObjectMemoryInfo", "UnityEditorInternal"); + MonoArray* object_array = mono_array_new(mono_domain_get(), klass, numberOfObjects); + + for (int i = 0; i < numberOfObjects;i++) + { + MonoObject* obj = mono_object_new (mono_domain_get(), klass); + GetMonoArrayElement (object_array,i) = obj; + } + + for (int i = 0; i < numberOfObjects;i++) + { + MonoObjectMemoryInfo& memInfo = ExtractMonoObjectData (GetMonoArrayElement (object_array,i)); + memInfo.instanceId = *current_offset++; + memInfo.memorySize = *current_offset++; + memInfo.count = *current_offset++; + memInfo.reason = *current_offset++; + std::string name; + std::string className; + ReadString(¤t_offset, name, swapdata); + ReadString(¤t_offset, className, swapdata); + memInfo.name = MonoStringNew(name); + memInfo.className = MonoStringNew(className); + } + + Assert(*current_offset==OBJECT_MEMORY_STREAM_TAIL); + + *objectArray = object_array; + *referenceArray = reference_array; +} + +void DeserializeAndApply (const void* data, size_t size) +{ + MonoArray* objectArray; + MonoArray* indexArray; + Deserialize (data, size, &objectArray, &indexArray); + + ScriptingInvocation invocation ("UnityEditor", "ProfilerWindow", "SetMemoryProfilerInfo"); + invocation.AddArray(objectArray); + invocation.AddArray(indexArray); + invocation.Invoke(); +} + +void SetDataFromEditor () +{ + dynamic_array data; + TakeMemorySnapshot(data); + DeserializeAndApply(data.begin(), data.size()*sizeof(int)); + +#if RECORD_ALLOCATION_SITES + MemoryProfiler::MemoryStackEntry* stack = GetMemoryProfiler()->GetStackOverview(); + MonoObject* obj = stack->Deserialize (); + void* arguments[] = { obj }; + CallStaticMonoMethod("MemoryProfiler", "SetMemoryProfilerStackInfo", arguments); + GetMemoryProfiler()->ClearStackOverview(stack); + + ProfilerString unrooted = GetMemoryProfiler()->GetUnrootedAllocationsOverview(); +#endif +} + +#endif +} + +#endif -- cgit v1.1-26-g67d0