Optimize dynamic memory allocations for managed runtime interop collections with a new Arena Allocation

This commit is contained in:
Wojtek Figat
2025-05-25 17:39:20 +02:00
parent 9aaba955d0
commit 8c62f1120f
13 changed files with 185 additions and 55 deletions

View File

@@ -815,7 +815,7 @@ namespace
{
MMethod* FindMethod(MClass* mclass, const MMethod* referenceMethod)
{
const Array<MMethod*>& methods = mclass->GetMethods();
const auto& methods = mclass->GetMethods();
for (int32 i = 0; i < methods.Count(); i++)
{
MMethod* method = methods[i];
@@ -1095,7 +1095,7 @@ void ManagedBinaryModule::InitType(MClass* mclass)
// Initialize scripting interfaces implemented in C#
int32 interfacesCount = 0;
MClass* klass = mclass;
const Array<MClass*>& interfaceClasses = klass->GetInterfaces();
const auto& interfaceClasses = klass->GetInterfaces();
for (const MClass* interfaceClass : interfaceClasses)
{
const ScriptingTypeHandle interfaceType = FindType(interfaceClass);

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Memory/ArenaAllocation.h"
#include "MTypes.h"
/// <summary>
@@ -25,12 +26,12 @@ private:
#endif
MAssembly* _assembly;
mutable Array<MMethod*> _methods;
mutable Array<MField*> _fields;
mutable Array<MProperty*> _properties;
mutable Array<MObject*> _attributes;
mutable Array<MEvent*> _events;
mutable Array<MClass*> _interfaces;
mutable Array<MMethod*, ArenaAllocation> _methods;
mutable Array<MField*, ArenaAllocation> _fields;
mutable Array<MProperty*, ArenaAllocation> _properties;
mutable Array<MObject*, ArenaAllocation> _attributes;
mutable Array<MEvent*, ArenaAllocation> _events;
mutable Array<MClass*, ArenaAllocation> _interfaces;
MVisibility _visibility;
@@ -248,7 +249,7 @@ public:
/// </summary>
/// <remarks>Be aware this will not include the methods of any base classes.</remarks>
/// <returns>The list of methods.</returns>
const Array<MMethod*>& GetMethods() const;
const Array<MMethod*, ArenaAllocation>& GetMethods() const;
/// <summary>
/// Returns an object referencing a field with the specified name.
@@ -263,7 +264,7 @@ public:
/// </summary>
/// <remarks>Be aware this will not include the fields of any base classes.</remarks>
/// <returns>The list of fields.</returns>
const Array<MField*>& GetFields() const;
const Array<MField*, ArenaAllocation>& GetFields() const;
/// <summary>
/// Returns an object referencing a event with the specified name.
@@ -276,7 +277,7 @@ public:
/// Returns all events belonging to this class.
/// </summary>
/// <returns>The list of events.</returns>
const Array<MEvent*>& GetEvents() const;
const Array<MEvent*, ArenaAllocation>& GetEvents() const;
/// <summary>
/// Returns an object referencing a property with the specified name.
@@ -291,14 +292,14 @@ public:
/// </summary>
/// <remarks>Be aware this will not include the properties of any base classes.</remarks>
/// <returns>The list of properties.</returns>
const Array<MProperty*>& GetProperties() const;
const Array<MProperty*, ArenaAllocation>& GetProperties() const;
/// <summary>
/// Returns all interfaces implemented by this class (excluding interfaces from base classes).
/// </summary>
/// <remarks>Be aware this will not include the interfaces of any base classes.</remarks>
/// <returns>The list of interfaces.</returns>
const Array<MClass*>& GetInterfaces() const;
const Array<MClass*, ArenaAllocation>& GetInterfaces() const;
public:
/// <summary>
@@ -332,5 +333,5 @@ public:
/// Returns an instance of all attributes connected with given class. Returns null if the class doesn't have any attributes.
/// </summary>
/// <returns>The array of attribute objects.</returns>
const Array<MObject*>& GetAttributes() const;
const Array<MObject*, ArenaAllocation>& GetAttributes() const;
};

View File

@@ -29,7 +29,7 @@ protected:
mutable int32 _hasAddMonoMethod : 1;
mutable int32 _hasRemoveMonoMethod : 1;
mutable Array<MObject*> _attributes;
mutable Array<MObject*, ArenaAllocation> _attributes;
public:
#if USE_MONO
@@ -121,5 +121,5 @@ public:
/// Returns an instance of all attributes connected with given event. Returns null if the event doesn't have any attributes.
/// </summary>
/// <returns>The array of attribute objects.</returns>
const Array<MObject*>& GetAttributes() const;
const Array<MObject*, ArenaAllocation>& GetAttributes() const;
};

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Memory/ArenaAllocation.h"
#include "MTypes.h"
/// <summary>
@@ -32,7 +33,7 @@ protected:
mutable int32 _hasCachedAttributes : 1;
int32 _isStatic : 1;
mutable Array<MObject*> _attributes;
mutable Array<MObject*, ArenaAllocation> _attributes;
public:
#if USE_MONO
@@ -157,5 +158,5 @@ public:
/// Returns an instance of all attributes connected with given field. Returns null if the field doesn't have any attributes.
/// </summary>
/// <returns>The array of attribute objects.</returns>
const Array<MObject*>& GetAttributes() const;
const Array<MObject*, ArenaAllocation>& GetAttributes() const;
};

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Memory/ArenaAllocation.h"
#if COMPILE_WITH_PROFILER
#include "Engine/Profiler/ProfilerSrcLoc.h"
#endif
@@ -42,7 +43,7 @@ protected:
#endif
int32 _isStatic : 1;
mutable Array<MObject*> _attributes;
mutable Array<MObject*, ArenaAllocation> _attributes;
public:
#if USE_MONO
@@ -197,5 +198,5 @@ public:
/// Returns an instance of all attributes connected with given method. Returns null if the method doesn't have any attributes.
/// </summary>
/// <returns>The array of attribute objects.</returns>
const Array<MObject*>& GetAttributes() const;
const Array<MObject*, ArenaAllocation>& GetAttributes() const;
};

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Memory/ArenaAllocation.h"
#include "MTypes.h"
/// <summary>
@@ -31,7 +32,7 @@ protected:
mutable int32 _hasSetMethod : 1;
mutable int32 _hasGetMethod : 1;
mutable Array<MObject*> _attributes;
mutable Array<MObject*, ArenaAllocation> _attributes;
public:
#if USE_MONO
@@ -135,5 +136,5 @@ public:
/// Returns an instance of all attributes connected with given property. Returns null if the property doesn't have any attributes.
/// </summary>
/// <returns>The array of attribute objects.</returns>
const Array<MObject*>& GetAttributes() const;
const Array<MObject*, ArenaAllocation>& GetAttributes() const;
};

View File

@@ -212,7 +212,7 @@ MClass* GetClass(MType* typeHandle);
MClass* GetOrCreateClass(MType* typeHandle);
MType* GetObjectType(MObject* obj);
void* GetCustomAttribute(const Array<MObject*>& attributes, const MClass* attributeClass)
void* GetCustomAttribute(const Array<MObject*, ArenaAllocation>& attributes, const MClass* attributeClass)
{
for (MObject* attr : attributes)
{
@@ -223,7 +223,7 @@ void* GetCustomAttribute(const Array<MObject*>& attributes, const MClass* attrib
return nullptr;
}
void GetCustomAttributes(Array<MObject*>& result, void* handle, void* getAttributesFunc)
void GetCustomAttributes(Array<MObject*, ArenaAllocation>& result, void* handle, void* getAttributesFunc)
{
MObject** attributes;
int numAttributes;
@@ -922,6 +922,12 @@ MClass::MClass(MAssembly* parentAssembly, void* handle, const char* name, const
, _namespace(parentAssembly->AllocString(namespace_))
, _fullname(parentAssembly->AllocString(fullname))
, _assembly(parentAssembly)
, _methods(&parentAssembly->Memory)
, _fields(&parentAssembly->Memory)
, _properties(&parentAssembly->Memory)
, _attributes(&parentAssembly->Memory)
, _events(&parentAssembly->Memory)
, _interfaces(&parentAssembly->Memory)
, _hasCachedProperties(false)
, _hasCachedFields(false)
, _hasCachedMethods(false)
@@ -1050,7 +1056,7 @@ MMethod* MClass::GetMethod(const char* name, int32 numParams) const
return nullptr;
}
const Array<MMethod*>& MClass::GetMethods() const
const Array<MMethod*, ArenaAllocation>& MClass::GetMethods() const
{
if (_hasCachedMethods)
return _methods;
@@ -1089,7 +1095,7 @@ MField* MClass::GetField(const char* name) const
return nullptr;
}
const Array<MField*>& MClass::GetFields() const
const Array<MField*, ArenaAllocation>& MClass::GetFields() const
{
if (_hasCachedFields)
return _fields;
@@ -1116,7 +1122,7 @@ const Array<MField*>& MClass::GetFields() const
return _fields;
}
const Array<MEvent*>& MClass::GetEvents() const
const Array<MEvent*, ArenaAllocation>& MClass::GetEvents() const
{
if (_hasCachedEvents)
return _events;
@@ -1139,7 +1145,7 @@ MProperty* MClass::GetProperty(const char* name) const
return nullptr;
}
const Array<MProperty*>& MClass::GetProperties() const
const Array<MProperty*, ArenaAllocation>& MClass::GetProperties() const
{
if (_hasCachedProperties)
return _properties;
@@ -1166,7 +1172,7 @@ const Array<MProperty*>& MClass::GetProperties() const
return _properties;
}
const Array<MClass*>& MClass::GetInterfaces() const
const Array<MClass*, ArenaAllocation>& MClass::GetInterfaces() const
{
if (_hasCachedInterfaces)
return _interfaces;
@@ -1206,7 +1212,7 @@ MObject* MClass::GetAttribute(const MClass* klass) const
return (MObject*)GetCustomAttribute(GetAttributes(), klass);
}
const Array<MObject*>& MClass::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MClass::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1239,6 +1245,7 @@ MEvent::MEvent(MClass* parentClass, void* handle, const char* name)
, _hasCachedAttributes(false)
, _hasAddMonoMethod(true)
, _hasRemoveMonoMethod(true)
, _attributes(&parentClass->GetAssembly()->Memory)
{
}
@@ -1267,7 +1274,7 @@ MObject* MEvent::GetAttribute(const MClass* klass) const
return (MObject*)GetCustomAttribute(GetAttributes(), klass);
}
const Array<MObject*>& MEvent::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MEvent::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1313,6 +1320,7 @@ MField::MField(MClass* parentClass, void* handle, const char* name, void* type,
, _parentClass(parentClass)
, _name(parentClass->GetAssembly()->AllocString(name))
, _hasCachedAttributes(false)
, _attributes(&parentClass->GetAssembly()->Memory)
{
switch (attributes & MFieldAttributes::FieldAccessMask)
{
@@ -1389,7 +1397,7 @@ MObject* MField::GetAttribute(const MClass* klass) const
return (MObject*)GetCustomAttribute(GetAttributes(), klass);
}
const Array<MObject*>& MField::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MField::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1410,6 +1418,7 @@ MMethod::MMethod(MClass* parentClass, StringAnsiView name, void* handle, int32 p
, _name(name)
, _hasCachedAttributes(false)
, _hasCachedSignature(false)
, _attributes(&parentClass->GetAssembly()->Memory)
{
switch (attributes & MMethodAttributes::MemberAccessMask)
{
@@ -1555,7 +1564,7 @@ MObject* MMethod::GetAttribute(const MClass* klass) const
return (MObject*)GetCustomAttribute(GetAttributes(), klass);
}
const Array<MObject*>& MMethod::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MMethod::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1584,6 +1593,7 @@ MProperty::MProperty(MClass* parentClass, const char* name, void* handle, void*
, _name(parentClass->GetAssembly()->AllocString(name))
, _handle(handle)
, _hasCachedAttributes(false)
, _attributes(&parentClass->GetAssembly()->Memory)
{
_hasGetMethod = getterHandle != nullptr;
if (_hasGetMethod)
@@ -1644,7 +1654,7 @@ MObject* MProperty::GetAttribute(const MClass* klass) const
return (MObject*)GetCustomAttribute(GetAttributes(), klass);
}
const Array<MObject*>& MProperty::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MProperty::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;

View File

@@ -1539,7 +1539,7 @@ MObject* MClass::GetAttribute(const MClass* klass) const
return attrInfo ? mono_custom_attrs_get_attr(attrInfo, klass->GetNative()) : nullptr;
}
const Array<MObject*>& MClass::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MClass::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1662,7 +1662,7 @@ MObject* MEvent::GetAttribute(const MClass* klass) const
return foundAttr;
}
const Array<MObject*>& MEvent::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MEvent::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1815,7 +1815,7 @@ MObject* MField::GetAttribute(const MClass* klass) const
return foundAttr;
}
const Array<MObject*>& MField::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MField::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -1988,7 +1988,7 @@ MObject* MMethod::GetAttribute(const MClass* klass) const
return foundAttr;
}
const Array<MObject*>& MMethod::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MMethod::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;
@@ -2118,7 +2118,7 @@ MObject* MProperty::GetAttribute(const MClass* klass) const
return foundAttr;
}
const Array<MObject*>& MProperty::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MProperty::GetAttributes() const
{
if (_hasCachedAttributes)
return _attributes;

View File

@@ -358,7 +358,7 @@ MMethod* MClass::GetMethod(const char* name, int32 numParams) const
return nullptr;
}
const Array<MMethod*>& MClass::GetMethods() const
const Array<MMethod*, ArenaAllocation>& MClass::GetMethods() const
{
_hasCachedMethods = true;
return _methods;
@@ -369,13 +369,13 @@ MField* MClass::GetField(const char* name) const
return nullptr;
}
const Array<MField*>& MClass::GetFields() const
const Array<MField*, ArenaAllocation>& MClass::GetFields() const
{
_hasCachedFields = true;
return _fields;
}
const Array<MEvent*>& MClass::GetEvents() const
const Array<MEvent*, ArenaAllocation>& MClass::GetEvents() const
{
_hasCachedEvents = true;
return _events;
@@ -386,7 +386,7 @@ MProperty* MClass::GetProperty(const char* name) const
return nullptr;
}
const Array<MProperty*>& MClass::GetProperties() const
const Array<MProperty*, ArenaAllocation>& MClass::GetProperties() const
{
_hasCachedProperties = true;
return _properties;
@@ -407,7 +407,7 @@ MObject* MClass::GetAttribute(const MClass* klass) const
return nullptr;
}
const Array<MObject*>& MClass::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MClass::GetAttributes() const
{
_hasCachedAttributes = true;
return _attributes;
@@ -449,7 +449,7 @@ MObject* MEvent::GetAttribute(const MClass* klass) const
return nullptr;
}
const Array<MObject*>& MEvent::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MEvent::GetAttributes() const
{
return _attributes;
}
@@ -501,7 +501,7 @@ MObject* MField::GetAttribute(const MClass* klass) const
return nullptr;
}
const Array<MObject*>& MField::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MField::GetAttributes() const
{
return _attributes;
}
@@ -556,7 +556,7 @@ MObject* MMethod::GetAttribute(const MClass* klass) const
return nullptr;
}
const Array<MObject*>& MMethod::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MMethod::GetAttributes() const
{
return _attributes;
}
@@ -603,7 +603,7 @@ MObject* MProperty::GetAttribute(const MClass* klass) const
return nullptr;
}
const Array<MObject*>& MProperty::GetAttributes() const
const Array<MObject*, ArenaAllocation>& MProperty::GetAttributes() const
{
return _attributes;
}