diff --git a/Development/Documentation/mono.md b/Development/Documentation/mono.md new file mode 100644 index 000000000..3f3267860 --- /dev/null +++ b/Development/Documentation/mono.md @@ -0,0 +1,13 @@ +## Mono + +Custom fork: [https://github.com/FlaxEngine/mono](https://github.com/FlaxEngine/mono) with custom features for C# assemblies hot-reloading at runtime without domain unload (more: [https://flaxengine.com/blog/flax-facts-16-scripts-hot-reload/](https://flaxengine.com/blog/flax-facts-16-scripts-hot-reload/)). + +### Notes + +Some useful notes and tips for devs: +* When working with mono fork set `localRepoPath` to local repo location in `Source\Tools\Flax.Build\Deps\Dependencies\mono.cs` +* To update mono deps when developing/updating use `.\Development\Scripts\Windows\CallBuildTool.bat -log -ReBuildDeps -verbose -depsToBuild=mono -platform=Windows`, then build engine and run it +* `MONO_GC_DEBUG=check-remset-consistency` - it will do additional checks at each collection to see if there are any missing write barriers +* `MONO_GC_DEBUG=nursery-canaries` - it might catch some buffer overflows in case of problems in code. +* Methods `mono_custom_attrs_from_property` and `mono_custom_attrs_get_attr` are internally cached +* If C++ mono call a method in c# that will throw an error, error will be handled but, not completly. Calling relase domain will return random `Access memory violation`. First search for error in c# code. No workaround yet. diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.Mono.cpp b/Source/Engine/Scripting/ManagedCLR/MCore.Mono.cpp index c69a2870b..7ab51d85b 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.Mono.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MCore.Mono.cpp @@ -115,6 +115,8 @@ void* MonoCalloc(size_t count, size_t size) #if USE_MONO_PROFILER +#include "Engine/Core/Types/StringBuilder.h" + struct FlaxMonoProfiler { }; @@ -123,7 +125,7 @@ FlaxMonoProfiler Profiler; struct StackWalkDataResult { - StringAnsi Buffer; + StringBuilder Buffer; }; mono_bool OnStackWalk(MonoMethod* method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data) @@ -135,16 +137,16 @@ mono_bool OnStackWalk(MonoMethod* method, int32_t native_offset, int32_t il_offs auto mName = mono_method_get_name(method); auto mKlassNameSpace = mono_class_get_namespace(mono_method_get_class(method)); auto mKlassName = mono_class_get_name(mono_method_get_class(method)); - result->Buffer += mKlassNameSpace; - result->Buffer += "."; - result->Buffer += mKlassName; - result->Buffer += "::"; - result->Buffer += mName; - result->Buffer += "\n"; + result->Buffer.Append(mKlassNameSpace); + result->Buffer.Append(TEXT(".")); + result->Buffer.Append(mKlassName); + result->Buffer.Append(TEXT("::")); + result->Buffer.Append(mName); + result->Buffer.Append(TEXT("\n")); } else if (!managed) { - result->Buffer += "\n"; + result->Buffer.Append(TEXT("\n")); } return 0; @@ -167,10 +169,10 @@ void OnGCAllocation(MonoProfiler* profiler, MonoObject* obj) if (details) { StackWalkDataResult stackTrace; - stackTrace.Buffer.reserve(1024); + stackTrace.Buffer.SetCapacity(1024); mono_stack_walk(&OnStackWalk, &stackTrace); - LOG(Info, "GC new: {0}.{1} ({2} bytes). Stack Trace:\n{3}", name_space, name, size, stackTrace.Buffer.c_str()); + LOG(Info, "GC new: {0}.{1} ({2} bytes). Stack Trace:\n{3}", String(name_space), String(name), size, stackTrace.Buffer.ToStringView()); } } #endif