| 462 | |
| 463 | // Main UI update entry point. |
| 464 | updateUi() { |
| 465 | // It is common to set 'overflow: hidden;' on canvas pages that do WebGL. When MemoryProfiler is being used, there will be a long block of text on the page, so force-enable scrolling. |
| 466 | if (document.body.style.overflow != '') document.body.style.overflow = ''; |
| 467 | function colorBar(color) { |
| 468 | return '<span style="padding:0px; border:solid 1px black; width:28px;height:14px; vertical-align:middle; display:inline-block; background-color:'+color+';"></span>'; |
| 469 | } |
| 470 | |
| 471 | // Naive function to compute how many bits will be needed to represent the number 'n' in binary. This will be our pointer 'word width' in the UI. |
| 472 | function nBits(n) { |
| 473 | var i = 0; |
| 474 | while (n >= 1) { |
| 475 | ++i; |
| 476 | n /= 2; |
| 477 | } |
| 478 | return i; |
| 479 | } |
| 480 | |
| 481 | // Returns i formatted to string as fixed-width hexadecimal. |
| 482 | function toHex(i, width) { |
| 483 | var str = i.toString(16); |
| 484 | while (str.length < width) str = '0' + str; |
| 485 | return '0x'+str; |
| 486 | } |
| 487 | |
| 488 | var self = emscriptenMemoryProfiler; |
| 489 | |
| 490 | // Poll whether user as changed the browser window, and if so, resize the profiler window and redraw it. |
| 491 | if (self.canvas.width != document.documentElement.clientWidth - 32) { |
| 492 | self.canvas.width = document.documentElement.clientWidth - 32; |
| 493 | } |
| 494 | |
| 495 | if (typeof runtimeInitialized != 'undefined' && !runtimeInitialized) { |
| 496 | return; |
| 497 | } |
| 498 | var stackBase = _emscripten_stack_get_base(); |
| 499 | var stackMax = _emscripten_stack_get_end(); |
| 500 | var stackCurrent = _emscripten_stack_get_current(); |
| 501 | var width = (nBits(HEAP8.length) + 3) / 4; // Pointer 'word width' |
| 502 | var html = 'Total HEAP size: ' + self.formatBytes(HEAP8.length) + '.'; |
| 503 | html += '<br />' + colorBar('#202020') + 'STATIC memory area size: ' + self.formatBytes(stackMax - {{{ GLOBAL_BASE }}}); |
| 504 | html += '. {{{ GLOBAL_BASE }}}: ' + toHex({{{ GLOBAL_BASE }}}, width); |
| 505 | |
| 506 | html += '<br />' + colorBar('#FF8080') + 'STACK memory area size: ' + self.formatBytes(stackBase - stackMax); |
| 507 | html += '. STACK_BASE: ' + toHex(stackBase, width); |
| 508 | html += '. STACKTOP: ' + toHex(stackCurrent, width); |
| 509 | html += '. STACK_MAX: ' + toHex(stackMax, width) + '.'; |
| 510 | html += '<br />STACK memory area used now (should be zero): ' + self.formatBytes(stackBase - stackCurrent) + '.' + colorBar('#FFFF00') + ' STACK watermark highest seen usage (approximate lower-bound!): ' + self.formatBytes(stackBase - self.stackTopWatermark); |
| 511 | |
| 512 | var heap_base = ___heap_base; |
| 513 | var heap_end = _sbrk({{{ to64('0') }}}); |
| 514 | html += "<br />DYNAMIC memory area size: " + self.formatBytes(heap_end - heap_base); |
| 515 | html += ". start: " + toHex(heap_base, width); |
| 516 | html += ". end: " + toHex(heap_end, width) + "."; |
| 517 | html += "<br />" + colorBar("#6699CC") + colorBar("#003366") + colorBar("#0000FF") + "DYNAMIC memory area used: " + self.formatBytes(self.totalMemoryAllocated) + " (" + (self.totalMemoryAllocated * 100 / (HEAP8.length - heap_base)).toFixed(2) + "% of all dynamic memory and unallocated heap)"; |
| 518 | html += "<br />Free memory: " + colorBar("#70FF70") + "DYNAMIC: " + self.formatBytes(heap_end - heap_base - self.totalMemoryAllocated) + ", " + colorBar('#FFFFFF') + 'Unallocated HEAP: ' + self.formatBytes(HEAP8.length - heap_end) + " (" + ((HEAP8.length - heap_base - self.totalMemoryAllocated) * 100 / (HEAP8.length - heap_base)).toFixed(2) + "% of all dynamic memory and unallocated heap)"; |
| 519 | |
| 520 | var preloadedMemoryUsed = 0; |
| 521 | for (var i in self.sizeOfPreRunAllocatedPtr) preloadedMemoryUsed += self.sizeOfPreRunAllocatedPtr[i]|0; |