MCPcopy Create free account
hub / github.com/GNOME/gjs / gjs_dump_memory_info

Function gjs_dump_memory_info

modules/system.cpp:181–251  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

179}
180
181static bool gjs_dump_memory_info(JSContext* cx, unsigned argc, JS::Value* vp) {
182 JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
183
184 Gjs::AutoChar filename;
185 if (!gjs_parse_call_args(cx, "dumpMemoryInfo", args, "|F", "filename",
186 &filename))
187 return false;
188
189 int64_t gc_counters[Gjs::GCCounters::N_COUNTERS];
190
191 // The object returned from NewMemoryInfoObject has gcBytes and mallocBytes
192 // properties which are the sum (over all zones) of bytes used. gcBytes is
193 // the number of bytes in garbage-collectable things (GC things).
194 // mallocBytes is the number of bytes allocated with malloc (reported with
195 // JS::AddAssociatedMemory).
196 //
197 // This info leaks internal state of the JS engine, which is why it is not
198 // returned to the caller, only dumped to a file and piped to Sysprof.
199 //
200 // The object also has a zone property with its own gcBytes and mallocBytes
201 // properties, representing the bytes used in the zone that the memory
202 // object belongs to. We only have one zone in GJS's context, so
203 // zone.gcBytes and zone.mallocBytes are a good measure for how much memory
204 // the actual user program is occupying. These are the values that we expose
205 // as counters in Sysprof. The difference between these values and the sum
206 // values is due to the self-hosting zone and atoms zone, that represent
207 // overhead of the JS engine.
208
209 JS::RootedObject gc_info(cx, js::gc::NewMemoryInfoObject(cx));
210 if (!gc_info)
211 return false;
212
213 const GjsAtoms& atoms = GjsContextPrivate::atoms(cx);
214 int32_t val;
215 JS::RootedObject zone_info(cx);
216 if (!gjs_object_require_property(cx, gc_info, "gc.zone", atoms.zone(),
217 &zone_info) ||
218 !gjs_object_require_property(cx, zone_info, "gc.zone.gcBytes",
219 atoms.gc_bytes(), &val))
220 return false;
221 gc_counters[Gjs::GCCounters::GC_HEAP_BYTES] = static_cast<int64_t>(val);
222 if (!gjs_object_require_property(cx, zone_info, "gc.zone.mallocBytes",
223 atoms.malloc_bytes(), &val))
224 return false;
225 gc_counters[Gjs::GCCounters::MALLOC_HEAP_BYTES] = static_cast<int64_t>(val);
226
227 auto* gjs = GjsContextPrivate::from_cx(cx);
228 if (gjs->profiler() &&
229 !gjs_profiler_sample_gc_memory_info(gjs->profiler(), gc_counters)) {
230 gjs_throw(cx, "Could not write GC counters to profiler");
231 return false;
232 }
233
234 LogFile file(filename);
235 if (file.has_error()) {
236 gjs_throw(cx, "Cannot dump memory info to %s: %s", filename.get(),
237 file.errmsg());
238 return false;

Callers

nothing calls this directly

Calls 9

gjs_parse_call_argsFunction · 0.85
gjs_throwFunction · 0.85
profilerMethod · 0.80
has_errorMethod · 0.80
errmsgMethod · 0.80
fpMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected