1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Optimize gdvirtual layout.

Co-authored-by: David Snopek <dsnopek@gmail.com>
This commit is contained in:
Yufeng Ying
2025-03-17 13:17:33 +08:00
parent 8bd9cdeea6
commit 057858a0fb
3 changed files with 50 additions and 43 deletions

View File

@@ -15,57 +15,65 @@ script_has_method = """ScriptInstance *_script_instance = ((Object *)(this))->ge
}""" }"""
proto = """#define GDVIRTUAL$VER($ALIAS $RET m_name $ARG)\\ proto = """#define GDVIRTUAL$VER($ALIAS $RET m_name $ARG)\\
StringName _gdvirtual_##$VARNAME##_sn = #m_name;\\
mutable bool _gdvirtual_##$VARNAME##_initialized = false;\\
mutable void *_gdvirtual_##$VARNAME = nullptr;\\ mutable void *_gdvirtual_##$VARNAME = nullptr;\\
_FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_call($CALLARGS) $CONST {\\ _FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_call($CALLARGS) $CONST {\\
static const StringName _gdvirtual_##$VARNAME##_sn = _scs_create(#m_name, true);\\
$SCRIPTCALL\\ $SCRIPTCALL\\
if (unlikely(_get_extension() && !_gdvirtual_##$VARNAME##_initialized)) {\\ if (_get_extension()) {\\
MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ if (unlikely(!_gdvirtual_##$VARNAME)) {\\
uint32_t hash = mi.get_compatibility_hash();\\ MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\
_gdvirtual_##$VARNAME = nullptr;\\ uint32_t hash = mi.get_compatibility_hash();\\
if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ _gdvirtual_##$VARNAME = nullptr;\\
_gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\
} else if (_get_extension()->get_virtual2) {\\ _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\
_gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ } else if (_get_extension()->get_virtual2) {\\
_gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\
}\\
_GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\
_GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME);\\
if (_gdvirtual_##$VARNAME == nullptr) {\\
_gdvirtual_##$VARNAME = reinterpret_cast<void*>(_INVALID_GDVIRTUAL_FUNC_ADDR);\\
}\\
}\\ }\\
_GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ if (_gdvirtual_##$VARNAME != reinterpret_cast<void*>(_INVALID_GDVIRTUAL_FUNC_ADDR)) {\\
_GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_initialized);\\ $CALLPTRARGS\\
_gdvirtual_##$VARNAME##_initialized = true;\\ $CALLPTRRETDEF\\
}\\ if (_get_extension()->call_virtual_with_data) {\\
if (_gdvirtual_##$VARNAME) {\\ _get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\
$CALLPTRARGS\\ $CALLPTRRET\\
$CALLPTRRETDEF\\ } else {\\
if (_get_extension()->call_virtual_with_data) {\\ ((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\
_get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\ $CALLPTRRET\\
$CALLPTRRET\\ }\\
} else {\\ return true;\\
((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\
$CALLPTRRET\\
}\\ }\\
return true;\\
}\\ }\\
$REQCHECK\\ $REQCHECK\\
$RVOID\\ $RVOID\\
return false;\\ return false;\\
}\\ }\\
_FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_overridden() const {\\ _FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_overridden() const {\\
static const StringName _gdvirtual_##$VARNAME##_sn = _scs_create(#m_name, true);\\
$SCRIPTHASMETHOD\\ $SCRIPTHASMETHOD\\
if (unlikely(_get_extension() && !_gdvirtual_##$VARNAME##_initialized)) {\\ if (_get_extension()) {\\
MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ if (unlikely(!_gdvirtual_##$VARNAME)) {\\
uint32_t hash = mi.get_compatibility_hash();\\ MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\
_gdvirtual_##$VARNAME = nullptr;\\ uint32_t hash = mi.get_compatibility_hash();\\
if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ _gdvirtual_##$VARNAME = nullptr;\\
_gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\
} else if (_get_extension()->get_virtual2) {\\ _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\
_gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ } else if (_get_extension()->get_virtual2) {\\
_gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\
}\\
_GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\
_GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME);\\
if (_gdvirtual_##$VARNAME == nullptr) {\\
_gdvirtual_##$VARNAME = reinterpret_cast<void*>(_INVALID_GDVIRTUAL_FUNC_ADDR);\\
}\\
}\\
if (_gdvirtual_##$VARNAME != reinterpret_cast<void*>(_INVALID_GDVIRTUAL_FUNC_ADDR)) {\\
return true;\\
}\\ }\\
_GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\
_GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_initialized);\\
_gdvirtual_##$VARNAME##_initialized = true;\\
}\\
if (_gdvirtual_##$VARNAME) {\\
return true;\\
}\\ }\\
return false;\\ return false;\\
}\\ }\\
@@ -211,17 +219,18 @@ def run(target, source, env):
#include "core/object/script_instance.h" #include "core/object/script_instance.h"
inline constexpr uintptr_t _INVALID_GDVIRTUAL_FUNC_ADDR = static_cast<uintptr_t>(-1);
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
#define _GDVIRTUAL_TRACK(m_virtual, m_initialized)\\ #define _GDVIRTUAL_TRACK(m_virtual)\\
if (_get_extension()->reloadable) {\\ if (_get_extension()->reloadable) {\\
VirtualMethodTracker *tracker = memnew(VirtualMethodTracker);\\ VirtualMethodTracker *tracker = memnew(VirtualMethodTracker);\\
tracker->method = (void **)&m_virtual;\\ tracker->method = (void **)&m_virtual;\\
tracker->initialized = &m_initialized;\\
tracker->next = virtual_method_list;\\ tracker->next = virtual_method_list;\\
virtual_method_list = tracker;\\ virtual_method_list = tracker;\\
} }
#else #else
#define _GDVIRTUAL_TRACK(m_virtual, m_initialized) #define _GDVIRTUAL_TRACK(m_virtual)
#endif #endif
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED

View File

@@ -2108,7 +2108,6 @@ void Object::clear_internal_extension() {
// Clear the virtual methods. // Clear the virtual methods.
while (virtual_method_list) { while (virtual_method_list) {
(*virtual_method_list->method) = nullptr; (*virtual_method_list->method) = nullptr;
(*virtual_method_list->initialized) = false;
virtual_method_list = virtual_method_list->next; virtual_method_list = virtual_method_list->next;
} }
} }

View File

@@ -764,7 +764,6 @@ protected:
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
struct VirtualMethodTracker { struct VirtualMethodTracker {
void **method; void **method;
bool *initialized;
VirtualMethodTracker *next; VirtualMethodTracker *next;
}; };