justjake / quickjs-emscripten

Safely execute untrusted Javascript in your Javascript, and execute synchronous code that uses async functions
https://www.npmjs.com/package/quickjs-emscripten
Other
1.27k stars 95 forks source link

Getting accurate readings of Memory #206

Open jsProj opened 2 weeks ago

jsProj commented 2 weeks ago

How would I go about getting memory accurate readings? When doing

(async () => {
    let QJS = await QuickJS.getQuickJS();
    let rt = QJS.newRuntime();
    let memoryLimit = 1024 * 32; // 32 KiB
    rt.setMemoryLimit(memoryLimit);
    rt.setMaxStackSize(2048);
    console.log(rt.computeMemoryUsage().consume(rt.getSystemContext().dump));
})().catch(console.error);

I get the result of

{
  malloc_limit: 32768, // bytes limit provided
  memory_used_size: 43402, // past bytes limit
  malloc_count: 835,
  memory_used_count: 835,
  atom_count: 486,
  atom_size: 16490,
  str_count: 0,
  str_size: 0,
  obj_count: 145,
  obj_size: 6960,
  prop_count: 806,
  prop_size: 6968,
  shape_count: 52,
  shape_size: 10896,
  js_func_count: 0,
  js_func_size: 0,
  js_func_code_size: 0,
  js_func_pc2line_count: 0,
  js_func_pc2line_size: 0,
  c_func_count: 91,
  array_count: 1,
  fast_array_count: 1,
  fast_array_elements: 0,
  binary_object_count: 0,
  binary_object_size: 0
}

Not to mention the memory_used_size, before any contexts other than the system context, scales with the allowed malloc_limit.

justjake commented 1 week ago

I looked into enabling better memory accounting, but there's a bug in Emscripten which prevents us from using Emscripten's malloc_usable_size function; quickjs hard-codes this to 0 in Emscripten environments, and Emscripten STRICT=1 mode appears to disable injectable memory.

Work-in-progress PR here: #207