diff options
author | Juan Linietsky <reduzio@gmail.com> | 2023-04-07 23:32:37 +0200 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2023-04-08 19:25:50 +0200 |
commit | 8950943356b43d08e10df5b13ff03a68ad181324 (patch) | |
tree | 2f301b4aa9d284ed620ac07c658453771f0728a6 | |
parent | 61630d4e1e279278d29576b979b710b9025f473e (diff) | |
download | redot-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.cpp | 5 | ||||
-rw-r--r-- | core/object/object.h | 30 | ||||
-rw-r--r-- | core/string/string_name.cpp | 8 | ||||
-rw-r--r-- | core/string/string_name.h | 2 |
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(); |