()
| 245 | |
| 246 | // Installs startup hook and periodic UI update timer. |
| 247 | initialize() { |
| 248 | // Inject the memoryprofiler hooks. |
| 249 | Module['onMalloc'] = (ptr, size, loc) => emscriptenMemoryProfiler.onMalloc(ptr, size, loc); |
| 250 | Module['onRealloc'] = (oldAddress, newAddress, size, loc) => emscriptenMemoryProfiler.onRealloc(oldAddress, newAddress, size, loc);; |
| 251 | Module['onFree'] = (ptr) => emscriptenMemoryProfiler.onFree(ptr); |
| 252 | Module['onSbrkGrow'] = (old_brk, new_brk, loc) => emscriptenMemoryProfiler.onSbrkGrow(old_brk, new_brk, loc); |
| 253 | emscriptenMemoryProfiler.recordStackWatermark(); |
| 254 | |
| 255 | // Add a tracking mechanism to detect when VFS loading is complete. |
| 256 | Module['preRun'] ??= []; |
| 257 | Module['preRun'].push(emscriptenMemoryProfiler.onPreloadComplete); |
| 258 | |
| 259 | if (emscriptenMemoryProfiler.hookStackAlloc && typeof stackAlloc == 'function') { |
| 260 | // Inject stack allocator. |
| 261 | var prevStackAlloc = stackAlloc; |
| 262 | var hookedStackAlloc = (size) => { |
| 263 | var ptr = prevStackAlloc(size); |
| 264 | emscriptenMemoryProfiler.recordStackWatermark(); |
| 265 | return ptr; |
| 266 | }; |
| 267 | stackAlloc = hookedStackAlloc; |
| 268 | } |
| 269 | |
| 270 | if (location.search.toLowerCase().includes('trackbytes=')) { |
| 271 | emscriptenMemoryProfiler.trackedCallstackMinSizeBytes = parseInt(location.search.slice(location.search.toLowerCase().indexOf('trackbytes=') + 'trackbytes='.length), undefined /* https://github.com/google/closure-compiler/issues/3230 / https://github.com/google/closure-compiler/issues/3548 */); |
| 272 | } |
| 273 | if (location.search.toLowerCase().includes('trackcount=')) { |
| 274 | emscriptenMemoryProfiler.trackedCallstackMinAllocCount = parseInt(location.search.slice(location.search.toLowerCase().indexOf('trackcount=') + 'trackcount='.length), undefined); |
| 275 | } |
| 276 | |
| 277 | emscriptenMemoryProfiler.memoryprofiler_summary = document.getElementById('memoryprofiler_summary'); |
| 278 | var div; |
| 279 | if (!emscriptenMemoryProfiler.memoryprofiler_summary) { |
| 280 | div = document.createElement("div"); |
| 281 | div.className = 'emscripten-memory-profiler-container'; |
| 282 | div.innerHTML = "<div style='border: 2px solid black; padding: 2px;'><canvas style='border: 1px solid black; margin-left: auto; margin-right: auto; display: block;' id='memoryprofiler_canvas' width='100%' height='50'></canvas><input type='checkbox' id='showHeapResizes' onclick='emscriptenMemoryProfiler.updateUi()'>Display heap and sbrk() resizes. Filter sbrk() and heap resize callstacks by keywords: <input type='text' id='sbrkFilter'>(reopen page with ?sbrkFilter=foo,bar query params to prepopulate this list)<br/>Track all allocation sites larger than <input id='memoryprofiler_min_tracked_alloc_size' type=number value="+emscriptenMemoryProfiler.trackedCallstackMinSizeBytes+"></input> bytes, and all allocation sites with more than <input id='memoryprofiler_min_tracked_alloc_count' type=number value="+emscriptenMemoryProfiler.trackedCallstackMinAllocCount+"></input> outstanding allocations. (visit this page via URL query params foo.html?trackbytes=1000&trackcount=100 to apply custom thresholds starting from page load)<br/><div id='memoryprofiler_summary'></div><input id='memoryprofiler_clear_alloc_stats' type='button' value='Clear alloc stats' ></input><br />Sort allocations by:<select id='memoryProfilerSort'><option value='bytes'>Bytes</option><option value='count'>Count</option><option value='fixed'>Fixed</option></select><div id='memoryprofiler_ptrs'></div>"; |
| 283 | } |
| 284 | var populateHtmlBody = function() { |
| 285 | if (div) { |
| 286 | document.body.appendChild(div); |
| 287 | |
| 288 | function getValueOfParam(key) { |
| 289 | var results = (new RegExp("[\\?&]"+key+"=([^&#]*)")).exec(location.href); |
| 290 | return results ? results[1] : ''; |
| 291 | } |
| 292 | // Allow specifying a precreated filter in page URL ?query parameters for convenience. |
| 293 | if (document.getElementById('sbrkFilter').value = getValueOfParam('sbrkFilter')) { |
| 294 | document.getElementById('showHeapResizes').checked = true; |
| 295 | } |
| 296 | } |
| 297 | var self = emscriptenMemoryProfiler; |
| 298 | self.memoryprofiler_summary = document.getElementById('memoryprofiler_summary'); |
| 299 | self.memoryprofiler_ptrs = document.getElementById('memoryprofiler_ptrs'); |
| 300 | |
| 301 | document.getElementById('memoryprofiler_min_tracked_alloc_size').addEventListener("change", function(e) { self.trackedCallstackMinSizeBytes=parseInt(this.value, undefined /* https://github.com/google/closure-compiler/issues/3230 / https://github.com/google/closure-compiler/issues/3548 */); }); |
| 302 | document.getElementById('memoryprofiler_min_tracked_alloc_count').addEventListener("change", function(e) { self.trackedCallstackMinAllocCount=parseInt(this.value, undefined); }); |
| 303 | document.getElementById('memoryprofiler_clear_alloc_stats').addEventListener("click", (e) => {self.allocationsAtLoc = {}; self.allocationSitePtrs = {};}); |
| 304 | self.canvas = document.getElementById('memoryprofiler_canvas'); |
nothing calls this directly
no test coverage detected