Implemented profiling functions for NativeScript

This commit is contained in:
Marcelo Fernandez 2018-08-20 12:14:52 -03:00
parent 75e540ce72
commit a323b7a1ba
5 changed files with 142 additions and 0 deletions

View file

@ -5876,6 +5876,14 @@
["int", "p_idx"],
["godot_object *", "p_object"]
]
},
{
"name": "godot_nativescript_profiling_add_data",
"return_type": "void",
"arguments": [
["const char *", "p_signature"],
["uint64_t", "p_line"]
]
}
]
},

View file

@ -238,6 +238,8 @@ void GDAPI godot_nativescript_unregister_instance_binding_data_functions(int p_i
void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object *p_object);
void GDAPI godot_nativescript_profiling_add_data(const char *p_signature, uint64_t p_time);
#ifdef __cplusplus
}
#endif

View file

@ -365,6 +365,10 @@ void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object
return NativeScriptLanguage::get_singleton()->get_instance_binding_data(p_idx, (Object *)p_object);
}
void GDAPI godot_nativescript_profiling_add_data(const char *p_signature, uint64_t p_time) {
NativeScriptLanguage::get_singleton()->profiling_add_data(StringName(p_signature), p_time);
}
#ifdef __cplusplus
}
#endif

View file

@ -1010,6 +1010,10 @@ NativeScriptLanguage::NativeScriptLanguage() {
has_objects_to_register = false;
mutex = Mutex::create();
#endif
#ifdef DEBUG_ENABLED
profiling = false;
#endif
}
NativeScriptLanguage::~NativeScriptLanguage() {
@ -1152,17 +1156,105 @@ void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_
}
void NativeScriptLanguage::profiling_start() {
#ifdef DEBUG_ENABLED
#ifndef NO_THREADS
MutexLock lock(mutex);
#endif
profile_data.clear();
profiling = true;
#endif
}
void NativeScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
#ifndef NO_THREADS
MutexLock lock(mutex);
#endif
profiling = false;
#endif
}
int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
#ifdef DEBUG_ENABLED
#ifndef NO_THREADS
MutexLock lock(mutex);
#endif
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
if (current >= p_info_max)
break;
p_info_arr[current].call_count = d->get().call_count;
p_info_arr[current].self_time = d->get().self_time;
p_info_arr[current].total_time = d->get().total_time;
p_info_arr[current].signature = d->get().signature;
current++;
}
return current;
#else
return 0;
#endif
}
int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
#ifdef DEBUG_ENABLED
#ifndef NO_THREADS
MutexLock lock(mutex);
#endif
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
if (current >= p_info_max)
break;
if (d->get().last_frame_call_count) {
p_info_arr[current].call_count = d->get().last_frame_call_count;
p_info_arr[current].self_time = d->get().last_frame_self_time;
p_info_arr[current].total_time = d->get().last_frame_total_time;
p_info_arr[current].signature = d->get().signature;
current++;
}
}
return current;
#else
return 0;
#endif
}
void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) {
#ifdef DEBUG_ENABLED
#ifndef NO_THREADS
MutexLock lock(mutex);
#endif
Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature);
if (d) {
d->get().call_count += 1;
d->get().total_time += p_time;
d->get().frame_call_count += 1;
d->get().frame_total_time += p_time;
} else {
ProfileData data;
data.signature = p_signature;
data.call_count = 1;
data.self_time = 0;
data.total_time = p_time;
data.frame_call_count = 1;
data.frame_self_time = 0;
data.frame_total_time = p_time;
data.last_frame_call_count = 0;
data.last_frame_self_time = 0;
data.last_frame_total_time = 0;
profile_data.insert(p_signature, data);
}
#endif
}
int NativeScriptLanguage::register_binding_functions(godot_instance_binding_functions p_binding_functions) {
@ -1405,6 +1497,24 @@ void NativeScriptLanguage::frame() {
has_objects_to_register = false;
}
#endif
#ifdef DEBUG_ENABLED
{
#ifndef NO_THREADS
MutexLock lock(mutex);
#endif
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
d->get().last_frame_call_count = d->get().frame_call_count;
d->get().last_frame_self_time = d->get().frame_self_time;
d->get().last_frame_total_time = d->get().frame_total_time;
d->get().frame_call_count = 0;
d->get().frame_self_time = 0;
d->get().frame_total_time = 0;
}
}
#endif
call_libraries_cb(_frame_call_name);
}

View file

@ -254,6 +254,22 @@ private:
Map<int, HashMap<StringName, const void *> > global_type_tags;
struct ProfileData {
StringName signature;
uint64_t call_count;
uint64_t self_time;
uint64_t total_time;
uint64_t frame_call_count;
uint64_t frame_self_time;
uint64_t frame_total_time;
uint64_t last_frame_call_count;
uint64_t last_frame_self_time;
uint64_t last_frame_total_time;
};
Map<StringName, ProfileData> profile_data;
bool profiling;
public:
// These two maps must only be touched on the main thread
Map<String, Map<StringName, NativeScriptDesc> > library_classes;
@ -343,6 +359,8 @@ public:
virtual bool handles_global_class_type(const String &p_type) const;
virtual String get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const;
void profiling_add_data(StringName p_signature, uint64_t p_time);
};
inline NativeScriptDesc *NativeScript::get_script_desc() const {