diff options
Diffstat (limited to 'modules/gdscript/gdscript.cpp')
-rw-r--r-- | modules/gdscript/gdscript.cpp | 115 |
1 files changed, 87 insertions, 28 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index ec1682d470..a999acd1bd 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1117,8 +1117,7 @@ GDScript *GDScript::find_class(const String &p_qualified_name) { // Starts at index 1 because index 0 was handled above. for (int i = 1; result != nullptr && i < class_names.size(); i++) { - String current_name = class_names[i]; - if (HashMap<StringName, Ref<GDScript>>::Iterator E = result->subclasses.find(current_name)) { + if (HashMap<StringName, Ref<GDScript>>::Iterator E = result->subclasses.find(class_names[i])) { result = E->value.ptr(); } else { // Couldn't find inner class. @@ -1156,8 +1155,8 @@ RBSet<GDScript *> GDScript::get_dependencies() { return dependencies; } -RBSet<GDScript *> GDScript::get_inverted_dependencies() { - RBSet<GDScript *> inverted_dependencies; +HashMap<GDScript *, RBSet<GDScript *>> GDScript::get_all_dependencies() { + HashMap<GDScript *, RBSet<GDScript *>> all_dependencies; List<GDScript *> scripts; { @@ -1171,51 +1170,42 @@ RBSet<GDScript *> GDScript::get_inverted_dependencies() { } for (GDScript *scr : scripts) { - if (scr == nullptr || scr == this || scr->destructing) { + if (scr == nullptr || scr->destructing) { continue; } - - RBSet<GDScript *> scr_dependencies = scr->get_dependencies(); - if (scr_dependencies.has(this)) { - inverted_dependencies.insert(scr); - } + all_dependencies.insert(scr, scr->get_dependencies()); } - return inverted_dependencies; + return all_dependencies; } RBSet<GDScript *> GDScript::get_must_clear_dependencies() { RBSet<GDScript *> dependencies = get_dependencies(); RBSet<GDScript *> must_clear_dependencies; - HashMap<GDScript *, RBSet<GDScript *>> inverted_dependencies; - - for (GDScript *E : dependencies) { - inverted_dependencies.insert(E, E->get_inverted_dependencies()); - } + HashMap<GDScript *, RBSet<GDScript *>> all_dependencies = get_all_dependencies(); RBSet<GDScript *> cant_clear; - for (KeyValue<GDScript *, RBSet<GDScript *>> &E : inverted_dependencies) { + for (KeyValue<GDScript *, RBSet<GDScript *>> &E : all_dependencies) { + if (dependencies.has(E.key)) { + continue; + } for (GDScript *F : E.value) { - if (!dependencies.has(F)) { - cant_clear.insert(E.key); - for (GDScript *G : E.key->get_dependencies()) { - cant_clear.insert(G); - } - break; + if (dependencies.has(F)) { + cant_clear.insert(F); } } } - for (KeyValue<GDScript *, RBSet<GDScript *>> &E : inverted_dependencies) { - if (cant_clear.has(E.key) || ScriptServer::is_global_class(E.key->get_fully_qualified_name())) { + for (GDScript *E : dependencies) { + if (cant_clear.has(E) || ScriptServer::is_global_class(E->get_fully_qualified_name())) { continue; } - must_clear_dependencies.insert(E.key); + must_clear_dependencies.insert(E); } cant_clear.clear(); dependencies.clear(); - inverted_dependencies.clear(); + all_dependencies.clear(); return must_clear_dependencies; } @@ -2230,6 +2220,8 @@ void GDScriptLanguage::profiling_start() { elem->self()->profile.last_frame_call_count = 0; elem->self()->profile.last_frame_self_time = 0; elem->self()->profile.last_frame_total_time = 0; + elem->self()->profile.native_calls.clear(); + elem->self()->profile.last_native_calls.clear(); elem = elem->next(); } @@ -2237,6 +2229,13 @@ void GDScriptLanguage::profiling_start() { #endif } +void GDScriptLanguage::profiling_set_save_native_calls(bool p_enable) { +#ifdef DEBUG_ENABLED + MutexLock lock(mutex); + profile_native_calls = p_enable; +#endif +} + void GDScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED MutexLock lock(this->mutex); @@ -2251,17 +2250,32 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, MutexLock lock(this->mutex); + profiling_collate_native_call_data(true); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { if (current >= p_info_max) { break; } + int last_non_internal = current; p_info_arr[current].call_count = elem->self()->profile.call_count.get(); p_info_arr[current].self_time = elem->self()->profile.self_time.get(); p_info_arr[current].total_time = elem->self()->profile.total_time.get(); p_info_arr[current].signature = elem->self()->profile.signature; - elem = elem->next(); current++; + + int nat_time = 0; + HashMap<String, GDScriptFunction::Profile::NativeProfile>::ConstIterator nat_calls = elem->self()->profile.native_calls.begin(); + while (nat_calls) { + p_info_arr[current].call_count = nat_calls->value.call_count; + p_info_arr[current].total_time = nat_calls->value.total_time; + p_info_arr[current].self_time = nat_calls->value.total_time; + p_info_arr[current].signature = nat_calls->value.signature; + nat_time += nat_calls->value.total_time; + current++; + ++nat_calls; + } + p_info_arr[last_non_internal].internal_time = nat_time; + elem = elem->next(); } #endif @@ -2274,17 +2288,33 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ #ifdef DEBUG_ENABLED MutexLock lock(this->mutex); + profiling_collate_native_call_data(false); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { if (current >= p_info_max) { break; } if (elem->self()->profile.last_frame_call_count > 0) { + int last_non_internal = current; p_info_arr[current].call_count = elem->self()->profile.last_frame_call_count; p_info_arr[current].self_time = elem->self()->profile.last_frame_self_time; p_info_arr[current].total_time = elem->self()->profile.last_frame_total_time; p_info_arr[current].signature = elem->self()->profile.signature; current++; + + int nat_time = 0; + HashMap<String, GDScriptFunction::Profile::NativeProfile>::ConstIterator nat_calls = elem->self()->profile.last_native_calls.begin(); + while (nat_calls) { + p_info_arr[current].call_count = nat_calls->value.call_count; + p_info_arr[current].total_time = nat_calls->value.total_time; + p_info_arr[current].self_time = nat_calls->value.total_time; + p_info_arr[current].internal_time = nat_calls->value.total_time; + p_info_arr[current].signature = nat_calls->value.signature; + nat_time += nat_calls->value.total_time; + current++; + ++nat_calls; + } + p_info_arr[last_non_internal].internal_time = nat_time; } elem = elem->next(); } @@ -2293,6 +2323,33 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ return current; } +void GDScriptLanguage::profiling_collate_native_call_data(bool p_accumulated) { +#ifdef DEBUG_ENABLED + // The same native call can be called from multiple functions, so join them together here. + // Only use the name of the function (ie signature.split[2]). + HashMap<String, GDScriptFunction::Profile::NativeProfile *> seen_nat_calls; + SelfList<GDScriptFunction> *elem = function_list.first(); + while (elem) { + HashMap<String, GDScriptFunction::Profile::NativeProfile> *nat_calls = p_accumulated ? &elem->self()->profile.native_calls : &elem->self()->profile.last_native_calls; + HashMap<String, GDScriptFunction::Profile::NativeProfile>::Iterator it = nat_calls->begin(); + + while (it != nat_calls->end()) { + Vector<String> sig = it->value.signature.split("::"); + HashMap<String, GDScriptFunction::Profile::NativeProfile *>::ConstIterator already_found = seen_nat_calls.find(sig[2]); + if (already_found) { + already_found->value->total_time += it->value.total_time; + already_found->value->call_count += it->value.call_count; + elem->self()->profile.last_native_calls.remove(it); + } else { + seen_nat_calls.insert(sig[2], &it->value); + } + ++it; + } + elem = elem->next(); + } +#endif +} + struct GDScriptDepSort { //must support sorting so inheritance works properly (parent must be reloaded first) bool operator()(const Ref<GDScript> &A, const Ref<GDScript> &B) const { @@ -2492,9 +2549,11 @@ void GDScriptLanguage::frame() { elem->self()->profile.last_frame_call_count = elem->self()->profile.frame_call_count.get(); elem->self()->profile.last_frame_self_time = elem->self()->profile.frame_self_time.get(); elem->self()->profile.last_frame_total_time = elem->self()->profile.frame_total_time.get(); + elem->self()->profile.last_native_calls = elem->self()->profile.native_calls; elem->self()->profile.frame_call_count.set(0); elem->self()->profile.frame_self_time.set(0); elem->self()->profile.frame_total_time.set(0); + elem->self()->profile.native_calls.clear(); elem = elem->next(); } } |