Move variant pools to their own compile unit.

This commit is contained in:
Lukas Tenbrink 2026-02-20 17:06:11 +01:00
parent be587f3a2d
commit e9465cd380
11 changed files with 197 additions and 52 deletions

View file

@ -33,6 +33,7 @@
#include "core/os/mutex.h"
#include "core/os/os.h"
#include "core/string/print_string.h"
#include "core/templates/paged_allocator.h"
struct StringName::Table {
constexpr static uint32_t TABLE_BITS = 16;

View file

@ -35,10 +35,7 @@
#include "core/io/resource.h"
#include "core/math/math_funcs.h"
#include "core/variant/variant_parser.h"
PagedAllocator<Variant::Pools::BucketSmall, true> Variant::Pools::_bucket_small;
PagedAllocator<Variant::Pools::BucketMedium, true> Variant::Pools::_bucket_medium;
PagedAllocator<Variant::Pools::BucketLarge, true> Variant::Pools::_bucket_large;
#include "core/variant/variant_pools.h"
String Variant::get_type_name(Variant::Type p_type) {
switch (p_type) {
@ -1172,7 +1169,7 @@ 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 = (Transform2D *)Pools::_bucket_small.alloc();
_data._transform2d = VariantPools::alloc<Transform2D>();
memnew_placement(_data._transform2d, Transform2D(*p_variant._data._transform2d));
} break;
case VECTOR3: {
@ -1191,22 +1188,22 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem)));
} break;
case AABB: {
_data._aabb = (::AABB *)Pools::_bucket_small.alloc();
_data._aabb = VariantPools::alloc<::AABB>();
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 = (Basis *)Pools::_bucket_medium.alloc();
_data._ptr = VariantPools::alloc<Basis>();
memnew_placement(_data._basis, Basis(*p_variant._data._basis));
} break;
case TRANSFORM3D: {
_data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc();
_data._ptr = VariantPools::alloc<Transform3D>();
memnew_placement(_data._transform3d, Transform3D(*p_variant._data._transform3d));
} break;
case PROJECTION: {
_data._projection = (Projection *)Pools::_bucket_large.alloc();
_data._ptr = VariantPools::alloc<Projection>();
memnew_placement(_data._projection, Projection(*p_variant._data._projection));
} break;
@ -1377,35 +1374,35 @@ void Variant::_clear_internal() {
case TRANSFORM2D: {
if (_data._transform2d) {
_data._transform2d->~Transform2D();
Pools::_bucket_small.free((Pools::BucketSmall *)_data._transform2d);
VariantPools::free(_data._transform2d);
_data._transform2d = nullptr;
}
} break;
case AABB: {
if (_data._aabb) {
_data._aabb->~AABB();
Pools::_bucket_small.free((Pools::BucketSmall *)_data._aabb);
VariantPools::free(_data._aabb);
_data._aabb = nullptr;
}
} break;
case BASIS: {
if (_data._basis) {
_data._basis->~Basis();
Pools::_bucket_medium.free((Pools::BucketMedium *)_data._basis);
VariantPools::free(_data._basis);
_data._basis = nullptr;
}
} break;
case TRANSFORM3D: {
if (_data._transform3d) {
_data._transform3d->~Transform3D();
Pools::_bucket_medium.free((Pools::BucketMedium *)_data._transform3d);
VariantPools::free(_data._transform3d);
_data._transform3d = nullptr;
}
} break;
case PROJECTION: {
if (_data._projection) {
_data._projection->~Projection();
Pools::_bucket_large.free((Pools::BucketLarge *)_data._projection);
VariantPools::free(_data._projection);
_data._projection = nullptr;
}
} break;
@ -2437,13 +2434,13 @@ Variant::Variant(const Plane &p_plane) :
Variant::Variant(const ::AABB &p_aabb) :
type(AABB) {
_data._aabb = (::AABB *)Pools::_bucket_small.alloc();
_data._aabb = VariantPools::alloc<::AABB>();
memnew_placement(_data._aabb, ::AABB(p_aabb));
}
Variant::Variant(const Basis &p_matrix) :
type(BASIS) {
_data._basis = (Basis *)Pools::_bucket_medium.alloc();
_data._basis = VariantPools::alloc<Basis>();
memnew_placement(_data._basis, Basis(p_matrix));
}
@ -2455,19 +2452,19 @@ Variant::Variant(const Quaternion &p_quaternion) :
Variant::Variant(const Transform3D &p_transform) :
type(TRANSFORM3D) {
_data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc();
_data._transform3d = VariantPools::alloc<Transform3D>();
memnew_placement(_data._transform3d, Transform3D(p_transform));
}
Variant::Variant(const Projection &pp_projection) :
type(PROJECTION) {
_data._projection = (Projection *)Pools::_bucket_large.alloc();
_data._projection = VariantPools::alloc<Projection>();
memnew_placement(_data._projection, Projection(pp_projection));
}
Variant::Variant(const Transform2D &p_transform) :
type(TRANSFORM2D) {
_data._transform2d = (Transform2D *)Pools::_bucket_small.alloc();
_data._transform2d = VariantPools::alloc<Transform2D>();
memnew_placement(_data._transform2d, Transform2D(p_transform));
}

View file

@ -54,7 +54,6 @@
#include "core/string/ustring.h"
#include "core/templates/bit_field.h"
#include "core/templates/list.h"
#include "core/templates/paged_allocator.h"
#include "core/templates/rid.h"
#include "core/variant/array.h"
#include "core/variant/callable.h"
@ -149,30 +148,6 @@ public:
};
private:
struct Pools {
union BucketSmall {
BucketSmall() {}
~BucketSmall() {}
Transform2D _transform2d;
::AABB _aabb;
};
union BucketMedium {
BucketMedium() {}
~BucketMedium() {}
Basis _basis;
Transform3D _transform3d;
};
union BucketLarge {
BucketLarge() {}
~BucketLarge() {}
Projection _projection;
};
static PagedAllocator<BucketSmall, true> _bucket_small;
static PagedAllocator<BucketMedium, true> _bucket_medium;
static PagedAllocator<BucketLarge, true> _bucket_large;
};
friend struct _VariantCall;
friend class VariantInternal;
template <typename>

View file

@ -30,10 +30,10 @@
#pragma once
#include "type_info.h"
#include "variant.h"
#include "core/templates/simple_type.h"
#include "core/variant/type_info.h"
#include "core/variant/variant.h"
#include "core/variant/variant_pools.h"
// 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.
@ -241,7 +241,7 @@ public:
v->type = Variant::STRING;
}
_FORCE_INLINE_ static void init_transform2d(Variant *v) {
v->_data._transform2d = (Transform2D *)Variant::Pools::_bucket_small.alloc();
v->_data._transform2d = VariantPools::alloc<Transform2D>();
memnew_placement(v->_data._transform2d, Transform2D);
v->type = Variant::TRANSFORM2D;
}
@ -250,22 +250,22 @@ public:
v->type = Variant::QUATERNION;
}
_FORCE_INLINE_ static void init_aabb(Variant *v) {
v->_data._aabb = (AABB *)Variant::Pools::_bucket_small.alloc();
v->_data._aabb = VariantPools::alloc<AABB>();
memnew_placement(v->_data._aabb, AABB);
v->type = Variant::AABB;
}
_FORCE_INLINE_ static void init_basis(Variant *v) {
v->_data._basis = (Basis *)Variant::Pools::_bucket_medium.alloc();
v->_data._basis = VariantPools::alloc<Basis>();
memnew_placement(v->_data._basis, Basis);
v->type = Variant::BASIS;
}
_FORCE_INLINE_ static void init_transform3d(Variant *v) {
v->_data._transform3d = (Transform3D *)Variant::Pools::_bucket_medium.alloc();
v->_data._transform3d = VariantPools::alloc<Transform3D>();
memnew_placement(v->_data._transform3d, Transform3D);
v->type = Variant::TRANSFORM3D;
}
_FORCE_INLINE_ static void init_projection(Variant *v) {
v->_data._projection = (Projection *)Variant::Pools::_bucket_large.alloc();
v->_data._projection = VariantPools::alloc<Projection>();
memnew_placement(v->_data._projection, Projection);
v->type = Variant::PROJECTION;
}

View file

@ -0,0 +1,93 @@
/**************************************************************************/
/* variant_pools.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "core/variant/variant_pools.h"
#include "core/math/aabb.h"
#include "core/math/projection.h"
#include "core/math/transform_2d.h"
#include "core/math/transform_3d.h"
#include "core/templates/paged_allocator.h"
namespace VariantPools {
union BucketSmall {
BucketSmall() {}
~BucketSmall() {}
Transform2D _transform2d;
::AABB _aabb;
};
static_assert(sizeof(BucketSmall) == VariantPools::BUCKET_SMALL);
static_assert(alignof(BucketSmall) == alignof(real_t));
union BucketMedium {
BucketMedium() {}
~BucketMedium() {}
Basis _basis;
Transform3D _transform3d;
};
static_assert(sizeof(BucketMedium) == VariantPools::BUCKET_MEDIUM);
static_assert(alignof(BucketMedium) == alignof(real_t));
union BucketLarge {
BucketLarge() {}
~BucketLarge() {}
Projection _projection;
};
static_assert(sizeof(BucketLarge) == VariantPools::BUCKET_LARGE);
static_assert(alignof(BucketLarge) == alignof(real_t));
} //namespace VariantPools
static PagedAllocator<VariantPools::BucketSmall, true> _bucket_small;
static PagedAllocator<VariantPools::BucketMedium, true> _bucket_medium;
static PagedAllocator<VariantPools::BucketLarge, true> _bucket_large;
void *VariantPools::alloc_small() {
return _bucket_small.alloc();
}
void *VariantPools::alloc_medium() {
return _bucket_medium.alloc();
}
void *VariantPools::alloc_large() {
return _bucket_large.alloc();
}
void VariantPools::free_small(void *p_ptr) {
_bucket_small.free(static_cast<BucketSmall *>(p_ptr));
}
void VariantPools::free_medium(void *p_ptr) {
_bucket_medium.free(static_cast<BucketMedium *>(p_ptr));
}
void VariantPools::free_large(void *p_ptr) {
_bucket_large.free(static_cast<BucketLarge *>(p_ptr));
}

View file

@ -0,0 +1,74 @@
/**************************************************************************/
/* variant_pools.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "core/math/math_defs.h"
#include "core/os/memory.h"
namespace VariantPools {
inline constexpr size_t BUCKET_SMALL = 2 * 3 * sizeof(real_t);
inline constexpr size_t BUCKET_MEDIUM = 4 * 3 * sizeof(real_t);
inline constexpr size_t BUCKET_LARGE = 4 * 4 * sizeof(real_t);
void *alloc_small();
void *alloc_medium();
void *alloc_large();
template <typename T>
_FORCE_INLINE_ T *alloc() {
if constexpr (sizeof(T) <= BUCKET_SMALL && alignof(real_t) % alignof(T) == 0) {
return static_cast<T *>(alloc_small());
} else if constexpr (sizeof(T) <= BUCKET_MEDIUM && alignof(real_t) % alignof(T) == 0) {
return static_cast<T *>(alloc_medium());
} else if constexpr (sizeof(T) <= BUCKET_LARGE && alignof(real_t) % alignof(T) == 0) {
return static_cast<T *>(alloc_large());
} else {
return memnew(T);
}
}
void free_small(void *p_ptr);
void free_medium(void *p_ptr);
void free_large(void *p_ptr);
template <typename T>
_FORCE_INLINE_ void free(T *p_ptr) {
if constexpr (sizeof(T) <= BUCKET_SMALL && alignof(real_t) % alignof(T) == 0) {
free_small(p_ptr);
} else if constexpr (sizeof(T) <= BUCKET_MEDIUM && alignof(real_t) % alignof(T) == 0) {
free_medium(p_ptr);
} else if constexpr (sizeof(T) <= BUCKET_LARGE && alignof(real_t) % alignof(T) == 0) {
free_large(p_ptr);
} else {
memdelete(p_ptr);
}
}
}; //namespace VariantPools

View file

@ -33,6 +33,7 @@
#include "detect_prime_egl.h"
#include "core/core_globals.h"
#include "core/string/print_string.h"
#include "core/variant/variant.h"

View file

@ -32,6 +32,7 @@
#include "detect_prime_x11.h"
#include "core/core_globals.h"
#include "core/string/print_string.h"
#include "core/variant/variant.h"

View file

@ -46,6 +46,7 @@
// ***********************************************************************************
#include "core/object/object.h"
#include "core/templates/paged_allocator.h"
#include "core/variant/type_info.h"
#include "servers/rendering/rendering_context_driver.h"
#include "servers/rendering/rendering_device_commons.h"

View file

@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "core/math/math_funcs_binary.h"
#include "tests/test_macros.h"
TEST_FORCE_LINK(test_math_funcs)

View file

@ -30,6 +30,7 @@
#pragma once
#include "core/core_globals.h" // IWYU pragma: Used in macro.
#include "core/variant/variant.h"
#if defined(_MSC_VER) && !defined(DOCTEST_THREAD_LOCAL)