summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2023-04-07 23:32:37 +0200
committerJuan Linietsky <reduzio@gmail.com>2023-04-08 19:25:50 +0200
commit8950943356b43d08e10df5b13ff03a68ad181324 (patch)
tree2f301b4aa9d284ed620ac07c658453771f0728a6
parent61630d4e1e279278d29576b979b710b9025f473e (diff)
downloadredot-engine-8950943356b43d08e10df5b13ff03a68ad181324.tar.gz
Optimize Object::get_class_name
* Run the static function once per class instead of one per instance. * Saves some memory in Object derived classes.
-rw-r--r--core/object/object.cpp5
-rw-r--r--core/object/object.h30
-rw-r--r--core/string/string_name.cpp8
-rw-r--r--core/string/string_name.h2
4 files changed, 28 insertions, 17 deletions
diff --git a/core/object/object.cpp b/core/object/object.cpp
index c324eab9bb..39cae7c5bd 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -195,14 +195,15 @@ bool Object::_predelete() {
_predelete_ok = 1;
notification(NOTIFICATION_PREDELETE, true);
if (_predelete_ok) {
- _class_ptr = nullptr; //must restore so destructors can access class ptr correctly
+ _class_name_ptr = nullptr; // Must restore, so constructors/destructors have proper class name access at each stage.
}
return _predelete_ok;
}
void Object::_postinitialize() {
- _class_ptr = _get_class_namev();
+ _class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after postinitialize.
_initialize_classv();
+ _class_name_ptr = nullptr; // May have been called from a constructor.
notification(NOTIFICATION_POSTINITIALIZE);
}
diff --git a/core/object/object.h b/core/object/object.h
index 5ec69a371b..4226b5e67b 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -376,7 +376,6 @@ private:
#define GDCLASS(m_class, m_inherits) \
private: \
void operator=(const m_class &p_rval) {} \
- mutable StringName _class_name; \
friend class ::ClassDB; \
\
public: \
@@ -388,13 +387,11 @@ public:
return String(#m_class); \
} \
virtual const StringName *_get_class_namev() const override { \
- if (_get_extension()) { \
- return &_get_extension()->class_name; \
- } \
- if (!_class_name) { \
- _class_name = get_class_static(); \
+ static StringName _class_name_static; \
+ if (unlikely(!_class_name_static)) { \
+ StringName::assign_static_unique_class_name(&_class_name_static, #m_class); \
} \
- return &_class_name; \
+ return &_class_name_static; \
} \
static _FORCE_INLINE_ void *get_class_ptr_static() { \
static int ptr; \
@@ -614,8 +611,7 @@ private:
Variant script; // Reference does not exist yet, store it in a Variant.
HashMap<StringName, Variant> metadata;
HashMap<StringName, Variant *> metadata_properties;
- mutable StringName _class_name;
- mutable const StringName *_class_ptr = nullptr;
+ mutable const StringName *_class_name_ptr = nullptr;
void _add_user_signal(const String &p_name, const Array &p_args = Array());
bool _has_user_signal(const StringName &p_name) const;
@@ -714,10 +710,11 @@ protected:
Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual const StringName *_get_class_namev() const {
- if (!_class_name) {
- _class_name = get_class_static();
+ static StringName _class_name_static;
+ if (unlikely(!_class_name_static)) {
+ StringName::assign_static_unique_class_name(&_class_name_static, "Object");
}
- return &_class_name;
+ return &_class_name_static;
}
Vector<StringName> _get_meta_list_bind() const;
@@ -788,13 +785,16 @@ public:
_FORCE_INLINE_ const StringName &get_class_name() const {
if (_extension) {
+ // Can't put inside the unlikely as constructor can run it
return _extension->class_name;
}
- if (!_class_ptr) {
+
+ if (unlikely(!_class_name_ptr)) {
+ // While class is initializing / deinitializing, constructors and destructurs
+ // need access to the proper class at the proper stage.
return *_get_class_namev();
- } else {
- return *_class_ptr;
}
+ return *_class_name_ptr;
}
/* IAPI */
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index df9b6b3f1a..6099fea13f 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -201,6 +201,14 @@ StringName::StringName(const StringName &p_name) {
}
}
+void StringName::assign_static_unique_class_name(StringName *ptr, const char *p_name) {
+ mutex.lock();
+ if (*ptr == StringName()) {
+ *ptr = StringName(p_name, true);
+ }
+ mutex.unlock();
+}
+
StringName::StringName(const char *p_name, bool p_static) {
_data = nullptr;
diff --git a/core/string/string_name.h b/core/string/string_name.h
index 177e82896d..07abc781a2 100644
--- a/core/string/string_name.h
+++ b/core/string/string_name.h
@@ -177,6 +177,8 @@ public:
StringName(const String &p_name, bool p_static = false);
StringName(const StaticCString &p_static_string, bool p_static = false);
StringName() {}
+
+ static void assign_static_unique_class_name(StringName *ptr, const char *p_name);
_FORCE_INLINE_ ~StringName() {
if (likely(configured) && _data) { //only free if configured
unref();