diff options
author | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-12-11 17:08:40 +0100 |
---|---|---|
committer | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2020-03-17 21:51:05 +0100 |
commit | 0b814ea78d6b065e8e0785155207bd80b3d845c8 (patch) | |
tree | 6513402706d55505ec57cf88c97db5633ffabb9a /modules/mono/mono_gd | |
parent | 989a223c5a6d6ba5b1b098be8983888cb49b2525 (diff) |
Mono/C#: Optimize the way we store GC handles for scripts
Don't store GC handles for C# script instances and instance bindings as 'Ref<MonoGCHandle>'; store the raw data instead. Initially this was not possible as we needed to store a Variant, but this had not been the case for a looong time yet the stored type was never updated.
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.cpp | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.cpp | 23 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.h | 5 |
5 files changed, 29 insertions, 9 deletions
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 7a3234b69b..418de87b5d 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -186,7 +186,7 @@ void CachedData::clear_godot_api_cache() { // End of MarshalUtils methods - task_scheduler_handle = Ref<MonoGCHandle>(); + task_scheduler_handle = Ref<MonoGCHandleRef>(); } #define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) @@ -316,7 +316,7 @@ void update_godot_api_cache() { // TODO Move to CSharpLanguage::init() and do handle disposal MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler)); - cached_data.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); + cached_data.task_scheduler_handle = MonoGCHandleRef::create_strong(task_scheduler); cached_data.godot_api_cache_updated = true; } diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 74a8d445c6..a0e1879c5a 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -156,7 +156,7 @@ struct CachedData { // End of MarshalUtils methods - Ref<MonoGCHandle> task_scheduler_handle; + Ref<MonoGCHandleRef> task_scheduler_handle; bool corlib_cache_updated; bool godot_api_cache_updated; diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index f343a1d646..53e642f317 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -75,7 +75,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { script_binding.inited = true; script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass); script_binding.wrapper_class = klass; - script_binding.gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); + script_binding.gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed); script_binding.owner = unmanaged; if (ref) { @@ -101,7 +101,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { return; } - Ref<MonoGCHandle> gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); + MonoGCHandleData gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed); Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index fa04183ea3..cdb26ae61b 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -86,10 +86,9 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { } } - Ref<MonoGCHandle> &gchandle = script_binding.gchandle; - ERR_FAIL_COND_V(gchandle.is_null(), NULL); + MonoGCHandleData &gchandle = script_binding.gchandle; - MonoObject *target = gchandle->get_target(); + MonoObject *target = gchandle.get_target(); if (target) return target; @@ -106,7 +105,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { MonoObject *mono_object = GDMonoUtils::create_managed_for_godot_object(script_binding.wrapper_class, script_binding.type_name, unmanaged); ERR_FAIL_NULL_V(mono_object, NULL); - gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE); + gchandle = MonoGCHandleData::new_strong_handle(mono_object); // Tie managed to unmanaged Reference *ref = Object::cast_to<Reference>(unmanaged); @@ -156,6 +155,22 @@ bool is_thread_attached() { return mono_domain_get() != NULL; } +uint32_t new_strong_gchandle(MonoObject *p_object) { + return mono_gchandle_new(p_object, /* pinned: */ false); +} + +uint32_t new_strong_gchandle_pinned(MonoObject *p_object) { + return mono_gchandle_new(p_object, /* pinned: */ true); +} + +uint32_t new_weak_gchandle(MonoObject *p_object) { + return mono_gchandle_new_weakref(p_object, /* track_resurrection: */ false); +} + +void free_gchandle(uint32_t p_gchandle) { + mono_gchandle_free(p_gchandle); +} + void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc) { GDMonoMethod *ctor = p_class->get_method(".ctor", 0); ERR_FAIL_NULL(ctor); diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 7b7afc44e0..fd02907d87 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -92,6 +92,11 @@ _FORCE_INLINE_ bool is_main_thread() { return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current(); } +uint32_t new_strong_gchandle(MonoObject *p_object); +uint32_t new_strong_gchandle_pinned(MonoObject *p_object); +uint32_t new_weak_gchandle(MonoObject *p_object); +void free_gchandle(uint32_t p_gchandle); + void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc = NULL); bool mono_delegate_equal(MonoDelegate *p_a, MonoDelegate *p_b); |