summaryrefslogtreecommitdiffstats
path: root/player/javascript.c
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2020-04-11 03:56:12 +0300
committeravih <avih@users.noreply.github.com>2020-11-15 20:36:04 +0200
commit932c1ada0f9b0f7078c09ef0179119c838eef84a (patch)
tree3628d293f6b3f449dd5e5b3898955f147addc112 /player/javascript.c
parentcc25137eaec92bcbe6c20632c644bfa9a2369a6a (diff)
downloadmpv-932c1ada0f9b0f7078c09ef0179119c838eef84a.tar.bz2
mpv-932c1ada0f9b0f7078c09ef0179119c838eef84a.tar.xz
js: report scripts CPU/memory usage statistics
This can be viewed at page 4 of the internal stats display (i or I). CPU time report is the same as at lua.c, but untested - doesn't seem to work on windows - also not for lua. TL;DR: Set env MPV_LEAK_REPORT=1 to enable js memory reporting stats. This also almost doubles the memory usage by js scripts. For memory reporting, we don't have enough info by default, because even when using a custom allocator, mujs doesn't report the old size (on free or realloc) because it doesn't track this value, and as a result we can't track the overall size. Our option are either to track the size of each allocation on our own, or use talloc which tracks this value. However, using talloc for mujs allocations adds a considerable overhead, and almost doubles(!) the overall memory used, because each individual allocation includes a considerable talloc header, and mujs does many small allocations. So our solution is that by default we behave like previously - not using a custom allocator with mujs, and stats does not display memory usage for js scripts. However, if the env var MPV_LEAK_REPORT is set to 1, then we use a custom allocator with talloc and track/report memory usage. We can't switch allocator at runtime, so an mpv instance either tracks or doesn't track js scripts memory usage, according to the env var. (we could use a property and apply it whenever a new script starts, so that it could change for newly launched scripts, but we don't).
Diffstat (limited to 'player/javascript.c')
-rw-r--r--player/javascript.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/player/javascript.c b/player/javascript.c
index be28ef9e66..7cffcbe119 100644
--- a/player/javascript.c
+++ b/player/javascript.c
@@ -33,6 +33,7 @@
#include "options/m_property.h"
#include "common/msg.h"
#include "common/msg_control.h"
+#include "common/stats.h"
#include "options/m_option.h"
#include "input/input.h"
#include "options/path.h"
@@ -64,6 +65,8 @@ struct script_ctx {
struct MPContext *mpctx;
struct mp_log *log;
char *last_error_str;
+ size_t js_malloc_size;
+ struct stats_ctx *stats;
};
static struct script_ctx *jctx(js_State *J)
@@ -458,6 +461,25 @@ static int s_init_js(js_State *J, struct script_ctx *ctx)
return 0;
}
+static void *mp_js_alloc(void *actx, void *ptr, int size_)
+{
+ if (size_ < 0)
+ return NULL;
+
+ struct script_ctx* ctx = actx;
+ size_t size = size_, osize = 0;
+ if (ptr) // free/realloc
+ osize = ta_get_size(ptr);
+
+ void *ret = talloc_realloc_size(actx, ptr, size);
+
+ if (!size || ret) { // free / successful realloc/malloc
+ ctx->js_malloc_size = ctx->js_malloc_size - osize + size;
+ stats_size_value(ctx->stats, "mem", ctx->js_malloc_size);
+ }
+ return ret;
+}
+
/**********************************************************************
* Initialization - booting the script
*********************************************************************/
@@ -479,10 +501,24 @@ static int s_load_javascript(struct mp_script_args *args)
.last_error_str = talloc_strdup(ctx, "Cannot initialize JavaScript"),
.filename = args->filename,
.path = args->path,
+ .js_malloc_size = 0,
+ .stats = stats_ctx_create(ctx, args->mpctx->global,
+ mp_tprintf(80, "script/%s", mpv_client_name(args->client))),
};
+ stats_register_thread_cputime(ctx->stats, "cpu");
+
+ js_Alloc alloc_fn = NULL;
+ void *actx = NULL;
+
+ char *mem_report = getenv("MPV_LEAK_REPORT");
+ if (mem_report && strcmp(mem_report, "1") == 0) {
+ alloc_fn = mp_js_alloc;
+ actx = ctx;
+ }
+
int r = -1;
- js_State *J = js_newstate(NULL, NULL, 0);
+ js_State *J = js_newstate(alloc_fn, actx, 0);
if (!J || s_init_js(J, ctx))
goto error_out;