Variant memory pools

Memory pools via PagedAllocator for Transform2D, Transform3D, Basis and AABB.
This commit is contained in:
lawnjelly 2022-05-20 13:28:44 +01:00
parent 1d06fec535
commit b221eab426
15 changed files with 185 additions and 42 deletions

View file

@ -39,6 +39,9 @@
#include "core/string/print_string.h"
#include "core/variant/variant_parser.h"
PagedAllocator<Variant::Pools::BucketSmall, true> Variant::Pools::_bucket_small;
PagedAllocator<Variant::Pools::BucketLarge, true> Variant::Pools::_bucket_large;
String Variant::get_type_name(Variant::Type p_type) {
switch (p_type) {
case NIL: {
@ -1076,7 +1079,8 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem)));
} break;
case TRANSFORM2D: {
_data._transform2d = memnew(Transform2D(*p_variant._data._transform2d));
_data._transform2d = (Transform2D *)Pools::_bucket_small.alloc();
memnew_placement(_data._transform2d, Transform2D(*p_variant._data._transform2d));
} break;
case VECTOR3: {
memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem)));
@ -1087,20 +1091,20 @@ void Variant::reference(const Variant &p_variant) {
case PLANE: {
memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem)));
} break;
case AABB: {
_data._aabb = memnew(::AABB(*p_variant._data._aabb));
_data._aabb = (::AABB *)Pools::_bucket_small.alloc();
memnew_placement(_data._aabb, ::AABB(*p_variant._data._aabb));
} break;
case QUATERNION: {
memnew_placement(_data._mem, Quaternion(*reinterpret_cast<const Quaternion *>(p_variant._data._mem)));
} break;
case BASIS: {
_data._basis = memnew(Basis(*p_variant._data._basis));
_data._basis = (Basis *)Pools::_bucket_large.alloc();
memnew_placement(_data._basis, Basis(*p_variant._data._basis));
} break;
case TRANSFORM3D: {
_data._transform3d = memnew(Transform3D(*p_variant._data._transform3d));
_data._transform3d = (Transform3D *)Pools::_bucket_large.alloc();
memnew_placement(_data._transform3d, Transform3D(*p_variant._data._transform3d));
} break;
// misc types
@ -1280,16 +1284,32 @@ void Variant::_clear_internal() {
RECT2
*/
case TRANSFORM2D: {
memdelete(_data._transform2d);
if (_data._transform2d) {
_data._transform2d->~Transform2D();
Pools::_bucket_small.free((Pools::BucketSmall *)_data._transform2d);
_data._transform2d = nullptr;
}
} break;
case AABB: {
memdelete(_data._aabb);
if (_data._aabb) {
_data._aabb->~AABB();
Pools::_bucket_small.free((Pools::BucketSmall *)_data._aabb);
_data._aabb = nullptr;
}
} break;
case BASIS: {
memdelete(_data._basis);
if (_data._basis) {
_data._basis->~Basis();
Pools::_bucket_large.free((Pools::BucketLarge *)_data._basis);
_data._basis = nullptr;
}
} break;
case TRANSFORM3D: {
memdelete(_data._transform3d);
if (_data._transform3d) {
_data._transform3d->~Transform3D();
Pools::_bucket_large.free((Pools::BucketLarge *)_data._transform3d);
_data._transform3d = nullptr;
}
} break;
// misc types
@ -2411,12 +2431,14 @@ Variant::Variant(const Plane &p_plane) {
Variant::Variant(const ::AABB &p_aabb) {
type = AABB;
_data._aabb = memnew(::AABB(p_aabb));
_data._aabb = (::AABB *)Pools::_bucket_small.alloc();
memnew_placement(_data._aabb, ::AABB(p_aabb));
}
Variant::Variant(const Basis &p_matrix) {
type = BASIS;
_data._basis = memnew(Basis(p_matrix));
_data._basis = (Basis *)Pools::_bucket_large.alloc();
memnew_placement(_data._basis, Basis(p_matrix));
}
Variant::Variant(const Quaternion &p_quaternion) {
@ -2426,12 +2448,14 @@ Variant::Variant(const Quaternion &p_quaternion) {
Variant::Variant(const Transform3D &p_transform) {
type = TRANSFORM3D;
_data._transform3d = memnew(Transform3D(p_transform));
_data._transform3d = (Transform3D *)Pools::_bucket_large.alloc();
memnew_placement(_data._transform3d, Transform3D(p_transform));
}
Variant::Variant(const Transform2D &p_transform) {
type = TRANSFORM2D;
_data._transform2d = memnew(Transform2D(p_transform));
_data._transform2d = (Transform2D *)Pools::_bucket_small.alloc();
memnew_placement(_data._transform2d, Transform2D(p_transform));
}
Variant::Variant(const Color &p_color) {

View file

@ -51,6 +51,7 @@
#include "core/os/keyboard.h"
#include "core/string/node_path.h"
#include "core/string/ustring.h"
#include "core/templates/paged_allocator.h"
#include "core/templates/rid.h"
#include "core/variant/array.h"
#include "core/variant/callable.h"
@ -128,6 +129,24 @@ public:
};
private:
struct Pools {
union BucketSmall {
BucketSmall() {}
~BucketSmall() {}
Transform2D _transform2d;
::AABB _aabb;
};
union BucketLarge {
BucketLarge() {}
~BucketLarge() {}
Basis _basis;
Transform3D _transform3d;
};
static PagedAllocator<BucketSmall, true> _bucket_small;
static PagedAllocator<BucketLarge, true> _bucket_large;
};
friend struct _VariantCall;
friend class VariantInternal;
// Variant takes 20 bytes when real_t is float, and 36 if double

View file

@ -36,6 +36,8 @@
// For use when you want to access the internal pointer of a Variant directly.
// Use with caution. You need to be sure that the type is correct.
class VariantInternal {
friend class Variant;
public:
// Set type.
_FORCE_INLINE_ static void initialize(Variant *v, Variant::Type p_type) {
@ -209,19 +211,23 @@ public:
}
_FORCE_INLINE_ static void init_transform2d(Variant *v) {
v->_data._transform2d = memnew(Transform2D);
v->_data._transform2d = (Transform2D *)Variant::Pools::_bucket_small.alloc();
memnew_placement(v->_data._transform2d, Transform2D);
v->type = Variant::TRANSFORM2D;
}
_FORCE_INLINE_ static void init_aabb(Variant *v) {
v->_data._aabb = memnew(AABB);
v->_data._aabb = (AABB *)Variant::Pools::_bucket_small.alloc();
memnew_placement(v->_data._aabb, AABB);
v->type = Variant::AABB;
}
_FORCE_INLINE_ static void init_basis(Variant *v) {
v->_data._basis = memnew(Basis);
v->_data._basis = (Basis *)Variant::Pools::_bucket_large.alloc();
memnew_placement(v->_data._basis, Basis);
v->type = Variant::BASIS;
}
_FORCE_INLINE_ static void init_transform(Variant *v) {
v->_data._transform3d = memnew(Transform3D);
v->_data._transform3d = (Transform3D *)Variant::Pools::_bucket_large.alloc();
memnew_placement(v->_data._transform3d, Transform3D);
v->type = Variant::TRANSFORM3D;
}
_FORCE_INLINE_ static void init_string_name(Variant *v) {