UNPKG

scichart

Version:

Fast WebGL JavaScript Charting Library and Framework

595 lines (594 loc) 29 kB
"use strict"; /** * WasmMemoryDebugHelper - TypeScript interface for WASM memory tracking * * This helper provides access to memory tracking data stored in window.__sciChartMemoryTracking * by the C++ memory override system. It allows toggling tracking flags and retrieving/logging * memory statistics. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.WasmMemoryDebugHelper = void 0; /** * WasmMemoryDebugHelper class - provides TypeScript interface to memory tracking * @ignore This is supposed to be available only during development in Debug Wasm build mode */ var WasmMemoryDebugHelper = /** @class */ (function () { function WasmMemoryDebugHelper() { } /** * Get the memory tracking object from window, or undefined if not initialized * @returns The memory tracking object with proper typing, or undefined */ WasmMemoryDebugHelper.getTracking = function () { return window.__sciChartMemoryTracking; }; /** * Get the window object with memory tracking property * @returns The window object (use getTracking() for typed access to memory tracking data) */ WasmMemoryDebugHelper.getWindow = function () { return window; }; /** * Check if memory tracking is initialized */ WasmMemoryDebugHelper.isInitialized = function () { return !!this.getTracking(); }; /** * Initialize memory tracking storage on the JavaScript side * This mirrors the C++ init_memory_tracking_storage function * Note: The C++ code automatically initializes this, but this method * can be called explicitly if needed for testing or manual initialization */ WasmMemoryDebugHelper.initializeTracking = function () { if (!window.__sciChartMemoryTracking) { window.__sciChartMemoryTracking = { // Malloc/Free tracking records: new Map(), allRecords: new Map(), mallocTimestamp: 0, mallocNextGuid: 1, // New/Delete tracking newRecords: new Map(), allNewRecords: new Map(), newDeleteTimestamp: 0, newDeleteNextGuid: 1, // Common settings stackTraceEnabled: true, mallocTrackingEnabled: true, newDeleteTrackingEnabled: true }; } }; // ============================================================================ // Flag Toggling Methods // ============================================================================ /** * Enable or disable stack trace capture for allocations */ WasmMemoryDebugHelper.setStackTraceEnabled = function (enabled) { var tracking = this.getTracking(); if (tracking) { tracking.stackTraceEnabled = enabled; } }; /** * Get current stack trace enabled state */ WasmMemoryDebugHelper.getStackTraceEnabled = function () { var tracking = this.getTracking(); return tracking ? tracking.stackTraceEnabled : true; }; /** * Enable or disable malloc/free tracking */ WasmMemoryDebugHelper.setMallocTrackingEnabled = function (enabled) { var tracking = this.getTracking(); if (tracking) { tracking.mallocTrackingEnabled = enabled; } }; /** * Get current malloc tracking enabled state */ WasmMemoryDebugHelper.getMallocTrackingEnabled = function () { var tracking = this.getTracking(); return tracking ? tracking.mallocTrackingEnabled : true; }; /** * Enable or disable new/delete tracking */ WasmMemoryDebugHelper.setNewDeleteTrackingEnabled = function (enabled) { var tracking = this.getTracking(); if (tracking) { tracking.newDeleteTrackingEnabled = enabled; } }; /** * Get current new/delete tracking enabled state */ WasmMemoryDebugHelper.getNewDeleteTrackingEnabled = function () { var tracking = this.getTracking(); return tracking ? tracking.newDeleteTrackingEnabled : true; }; // ============================================================================ // Helper Methods - Calculate Stats from Maps // ============================================================================ /** * Calculate statistics from a Map of memory records * @param map The Map to calculate stats from * @returns Statistics object with counts and byte totals */ WasmMemoryDebugHelper.calculateStatsFromMap = function (map) { var allocCount = 0; var deallocCount = 0; var totalAllocated = 0; var totalFreed = 0; for (var _i = 0, _a = Array.from(map.entries()); _i < _a.length; _i++) { var _b = _a[_i], record = _b[1]; allocCount++; totalAllocated += record.size; if (record.deallocated) { deallocCount++; totalFreed += record.size; } } return { allocCount: allocCount, deallocCount: deallocCount, totalAllocated: totalAllocated, totalFreed: totalFreed }; }; // ============================================================================ // Reset Methods // ============================================================================ /** * Reset malloc/free batch tracking - clears current batch records only * Preserves: allRecords Map (historical data) */ WasmMemoryDebugHelper.resetMallocBatch = function () { var tracking = this.getTracking(); if (tracking) { tracking.records.clear(); } }; /** * Reset new/delete batch tracking - clears current batch records only * Preserves: allNewRecords Map (historical data) */ WasmMemoryDebugHelper.resetNewDeleteBatch = function () { var tracking = this.getTracking(); if (tracking) { tracking.newRecords.clear(); } }; /** * Reset malloc/free historical data - clears historical records only * Clears: allRecords Map (historical) * Preserves: records Map (batch), timeline counters */ WasmMemoryDebugHelper.resetMallocHistorical = function () { var tracking = this.getTracking(); if (tracking) { tracking.allRecords.clear(); } }; /** * Reset new/delete historical data - clears historical records only * Clears: allNewRecords Map (historical) * Preserves: newRecords Map (batch), timeline counters */ WasmMemoryDebugHelper.resetNewDeleteHistorical = function () { var tracking = this.getTracking(); if (tracking) { tracking.allNewRecords.clear(); } }; /** * Reset all historical data - clears both malloc/free and new/delete historical records * Calls resetMallocHistorical() and resetNewDeleteHistorical() */ WasmMemoryDebugHelper.resetAllHistorical = function () { this.resetMallocHistorical(); this.resetNewDeleteHistorical(); }; /** * Reset everything - clears all batch and historical data for both malloc/free and new/delete * Clears all Maps (batch and historical) while preserving timeline counters * Calls all batch and historical reset methods */ WasmMemoryDebugHelper.resetAll = function () { this.resetMallocBatch(); this.resetNewDeleteBatch(); this.resetAllHistorical(); }; // ============================================================================ // Data Retrieval Methods - Malloc/Free // ============================================================================ /** * Get malloc/free memory statistics (calculated from allRecords - historical) */ WasmMemoryDebugHelper.getMallocStats = function () { var tracking = this.getTracking(); if (!tracking) { return { totalAllocations: 0, totalDeallocations: 0, currentAllocatedBytes: 0, peakAllocatedBytes: 0 }; } var stats = this.calculateStatsFromMap(tracking.allRecords); return { totalAllocations: stats.allocCount, totalDeallocations: stats.deallocCount, currentAllocatedBytes: stats.totalAllocated - stats.totalFreed, peakAllocatedBytes: stats.totalAllocated }; }; /** * Get current batch malloc/free records */ WasmMemoryDebugHelper.getMallocRecords = function () { var tracking = this.getTracking(); return tracking ? tracking.records : new Map(); }; /** * Get all historical malloc/free records */ WasmMemoryDebugHelper.getAllMallocRecords = function () { var tracking = this.getTracking(); return tracking ? tracking.allRecords : new Map(); }; // ============================================================================ // Data Retrieval Methods - New/Delete // ============================================================================ /** * Get new/delete memory statistics (calculated from allNewRecords - historical) */ WasmMemoryDebugHelper.getNewDeleteStats = function () { var tracking = this.getTracking(); if (!tracking) { return { totalAllocations: 0, totalDeallocations: 0, currentAllocatedBytes: 0, peakAllocatedBytes: 0 }; } var stats = this.calculateStatsFromMap(tracking.allNewRecords); return { totalAllocations: stats.allocCount, totalDeallocations: stats.deallocCount, currentAllocatedBytes: stats.totalAllocated - stats.totalFreed, peakAllocatedBytes: stats.totalAllocated }; }; /** * Get current batch new/delete records */ WasmMemoryDebugHelper.getNewDeleteRecords = function () { var tracking = this.getTracking(); return tracking ? tracking.newRecords : new Map(); }; /** * Get all historical new/delete records */ WasmMemoryDebugHelper.getAllNewDeleteRecords = function () { var tracking = this.getTracking(); return tracking ? tracking.allNewRecords : new Map(); }; // ============================================================================ // Console Logging Methods - Malloc/Free // ============================================================================ /** * Log current batch malloc/free allocations with detailed statistics * Stats are calculated from the records Map (current batch) */ WasmMemoryDebugHelper.logMallocBatch = function () { var tracking = this.getTracking(); if (!tracking) { console.warn("Memory tracking not initialized"); return; } var records = tracking.records; var batchStats = this.calculateStatsFromMap(records); // Calculate batch statistics var deletedCount = 0; var notDeletedCount = 0; var totalAllocatedBytes = 0; var notDeallocatedBytes = 0; var notDeletedRecords = []; var idx = 0; for (var _i = 0, _a = Array.from(records.entries()); _i < _a.length; _i++) { var _b = _a[_i], record = _b[1]; totalAllocatedBytes += record.size; if (record.deallocated) { deletedCount++; } else { notDeletedCount++; notDeallocatedBytes += record.size; notDeletedRecords.push({ record: record, index: idx }); } idx++; } var allocatedDiff = batchStats.totalAllocated - batchStats.totalFreed; var active = batchStats.allocCount - batchStats.deallocCount; console.groupCollapsed("[malloc/free] Memory Stats - Allocated Diff: ".concat(allocatedDiff, " bytes ") + "(Allocs: ".concat(batchStats.allocCount, ", Deallocs: ").concat(batchStats.deallocCount, ", Active: ").concat(active, ")")); console.log("[malloc/free] Total Allocated: ".concat(batchStats.totalAllocated, " bytes, ") + "Total Freed: ".concat(batchStats.totalFreed, " bytes, Current: ").concat(allocatedDiff, " bytes")); console.log("Batch Summary: ".concat(records.size, " allocations, ").concat(deletedCount, " deleted, ").concat(notDeletedCount, " not deleted")); console.log("Memory: ".concat(totalAllocatedBytes, " bytes allocated, ").concat(notDeallocatedBytes, " bytes not deallocated")); // Group 1: All batch allocations console.groupCollapsed("All Batch Allocations (".concat(records.size, " total: ").concat(deletedCount, " freed, ").concat(notDeletedCount, " active)")); var index = 0; for (var _c = 0, _d = Array.from(records.entries()); _c < _d.length; _c++) { var _e = _d[_c], guid = _e[0], record = _e[1]; var ptrStr = "0x".concat(record.ptr.toString(16)); var status_1 = record.deallocated ? " [FREED]" : " [ACTIVE]"; var deallocStr = record.deallocated ? " (freed at ".concat(record.deallocationTimestamp, ")") : ""; console.groupCollapsed("[".concat(index, "] [").concat(record.timestamp, "]: guid=").concat(guid, ", ptr=").concat(ptrStr, ", ").concat(record.size, "bt").concat(status_1).concat(deallocStr)); index++; if (record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); // Group 2: Non-deleted records (potential leaks) if (notDeletedRecords.length > 0) { console.groupCollapsed("Non-Deleted Records (".concat(notDeletedRecords.length, " active allocations, ").concat(notDeallocatedBytes, " bytes)")); for (var _f = 0, notDeletedRecords_1 = notDeletedRecords; _f < notDeletedRecords_1.length; _f++) { var item = notDeletedRecords_1[_f]; var ptrStr = "0x".concat(item.record.ptr.toString(16)); console.groupCollapsed("[".concat(item.index, "] [").concat(item.record.timestamp, "]: guid=").concat(item.record.guid, ", ptr=").concat(ptrStr, ", ").concat(item.record.size, "bt [ACTIVE]")); if (item.record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(item.record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); } console.groupEnd(); // Reset current batch tracking after logging this.resetMallocBatch(); }; /** * Log all historical malloc/free allocations (does not reset) * Stats are calculated from the allRecords Map (historical) */ WasmMemoryDebugHelper.logAllMallocAllocations = function () { var tracking = this.getTracking(); if (!tracking) { console.warn("Memory tracking not initialized"); return; } var allRecords = tracking.allRecords; var historicalStats = this.calculateStatsFromMap(allRecords); // Calculate statistics var activeCount = 0; var freedCount = 0; var totalAllocatedBytes = 0; var notDeallocatedBytes = 0; var notDeletedRecords = []; var idx = 0; for (var _i = 0, _a = Array.from(allRecords.entries()); _i < _a.length; _i++) { var _b = _a[_i], record = _b[1]; totalAllocatedBytes += record.size; if (record.deallocated) { freedCount++; } else { activeCount++; notDeallocatedBytes += record.size; notDeletedRecords.push({ record: record, index: idx }); } idx++; } var allocatedDiff = historicalStats.totalAllocated - historicalStats.totalFreed; var active = historicalStats.allocCount - historicalStats.deallocCount; console.groupCollapsed("[malloc/free] Memory Stats - Allocated Diff: ".concat(allocatedDiff, " bytes ") + "(Allocs: ".concat(historicalStats.allocCount, ", Deallocs: ").concat(historicalStats.deallocCount, ", Active: ").concat(active, ")")); console.log("[malloc/free] Total Allocated: ".concat(historicalStats.totalAllocated, " bytes, ") + "Total Freed: ".concat(historicalStats.totalFreed, " bytes, Current: ").concat(allocatedDiff, " bytes")); console.log("Historical Summary: ".concat(allRecords.size, " total allocations, ").concat(freedCount, " freed, ").concat(activeCount, " active")); console.log("Memory: ".concat(totalAllocatedBytes, " bytes allocated; ").concat(notDeallocatedBytes, " bytes not deallocated")); // Group 1: All historical allocations console.groupCollapsed("All Historical Allocations (".concat(allRecords.size, " total: ").concat(freedCount, " freed, ").concat(activeCount, " active)")); var index = 0; for (var _c = 0, _d = Array.from(allRecords.entries()); _c < _d.length; _c++) { var _e = _d[_c], guid = _e[0], record = _e[1]; var ptrStr = "0x".concat(record.ptr.toString(16)); var status_2 = record.deallocated ? " [FREED]" : " [ACTIVE]"; var deallocStr = record.deallocated ? " (freed at ".concat(record.deallocationTimestamp, ")") : ""; console.groupCollapsed("[".concat(index, "] [").concat(record.timestamp, "]: guid=").concat(guid, ", ptr=").concat(ptrStr, ", ").concat(record.size, "bt").concat(status_2).concat(deallocStr)); index++; if (record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); // Group 2: Non-deleted records (potential leaks) if (notDeletedRecords.length > 0) { console.groupCollapsed("Non-Deleted Records (".concat(notDeletedRecords.length, " active allocations; ").concat(notDeallocatedBytes, " bytes)")); for (var _f = 0, notDeletedRecords_2 = notDeletedRecords; _f < notDeletedRecords_2.length; _f++) { var item = notDeletedRecords_2[_f]; var ptrStr = "0x".concat(item.record.ptr.toString(16)); console.groupCollapsed("[".concat(item.index, "] [").concat(item.record.timestamp, "]: guid=").concat(item.record.guid, ", ptr=").concat(ptrStr, ", ").concat(item.record.size, "bt [ACTIVE]")); if (item.record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(item.record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); } console.groupEnd(); }; // ============================================================================ // Console Logging Methods - New/Delete // ============================================================================ /** * Log current batch new/delete allocations with detailed statistics * Stats are calculated from the newRecords Map (current batch) */ WasmMemoryDebugHelper.logNewDeleteBatch = function () { var tracking = this.getTracking(); if (!tracking) { console.warn("Memory tracking not initialized"); return; } var records = tracking.newRecords; var batchStats = this.calculateStatsFromMap(records); // Calculate batch statistics var deletedCount = 0; var notDeletedCount = 0; var totalAllocatedBytes = 0; var notDeallocatedBytes = 0; var notDeletedRecords = []; var idx = 0; for (var _i = 0, _a = Array.from(records.entries()); _i < _a.length; _i++) { var _b = _a[_i], record = _b[1]; totalAllocatedBytes += record.size; if (record.deallocated) { deletedCount++; } else { notDeletedCount++; notDeallocatedBytes += record.size; notDeletedRecords.push({ record: record, index: idx }); } idx++; } var allocatedDiff = batchStats.totalAllocated - batchStats.totalFreed; var active = batchStats.allocCount - batchStats.deallocCount; console.groupCollapsed("[new/delete] Memory Stats - Allocated Diff: ".concat(allocatedDiff, " bytes ") + "(News: ".concat(batchStats.allocCount, ", Deletes: ").concat(batchStats.deallocCount, ", Active: ").concat(active, ")")); console.log("[new/delete] Total Allocated: ".concat(batchStats.totalAllocated, " bytes, ") + "Total Deleted: ".concat(batchStats.totalFreed, " bytes, Current: ").concat(allocatedDiff, " bytes")); console.log("Batch Summary (new/delete): ".concat(records.size, " allocations, ").concat(deletedCount, " deleted, ").concat(notDeletedCount, " not deleted")); console.log("Memory: ".concat(totalAllocatedBytes, " bytes allocated, ").concat(notDeallocatedBytes, " bytes not deallocated")); // Group 1: All batch allocations console.groupCollapsed("All Batch New/Delete Allocations (".concat(records.size, " total: ").concat(deletedCount, " deleted, ").concat(notDeletedCount, " active)")); var index = 0; for (var _c = 0, _d = Array.from(records.entries()); _c < _d.length; _c++) { var _e = _d[_c], guid = _e[0], record = _e[1]; var ptrStr = "0x".concat(record.ptr.toString(16)); var status_3 = record.deallocated ? " [DELETED]" : " [ACTIVE]"; var deallocStr = record.deallocated ? " (deleted at ".concat(record.deallocationTimestamp, ")") : ""; console.groupCollapsed("[".concat(index, "] [").concat(record.timestamp, "]: guid=").concat(guid, ", ptr=").concat(ptrStr, ", ").concat(record.size, "bt").concat(status_3).concat(deallocStr)); index++; if (record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); // Group 2: Non-deleted records (potential leaks) if (notDeletedRecords.length > 0) { console.groupCollapsed("Non-Deleted Records (".concat(notDeletedRecords.length, " active allocations, ").concat(notDeallocatedBytes, " bytes)")); for (var _f = 0, notDeletedRecords_3 = notDeletedRecords; _f < notDeletedRecords_3.length; _f++) { var item = notDeletedRecords_3[_f]; var ptrStr = "0x".concat(item.record.ptr.toString(16)); console.groupCollapsed("[".concat(item.index, "] [").concat(item.record.timestamp, "]: guid=").concat(item.record.guid, ", ptr=").concat(ptrStr, ", ").concat(item.record.size, "bt [ACTIVE]")); if (item.record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(item.record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); } console.groupEnd(); // Reset current batch tracking after logging this.resetNewDeleteBatch(); }; /** * Log all historical new/delete allocations (does not reset) * Stats are calculated from the allNewRecords Map (historical) */ WasmMemoryDebugHelper.logAllNewDeleteAllocations = function () { var tracking = this.getTracking(); if (!tracking) { console.warn("Memory tracking not initialized"); return; } var allRecords = tracking.allNewRecords; var historicalStats = this.calculateStatsFromMap(allRecords); // Calculate statistics var activeCount = 0; var deletedCount = 0; var totalAllocatedBytes = 0; var notDeallocatedBytes = 0; var notDeletedRecords = []; var idx = 0; for (var _i = 0, _a = Array.from(allRecords.entries()); _i < _a.length; _i++) { var _b = _a[_i], record = _b[1]; totalAllocatedBytes += record.size; if (record.deallocated) { deletedCount++; } else { activeCount++; notDeallocatedBytes += record.size; notDeletedRecords.push({ record: record, index: idx }); } idx++; } var allocatedDiff = historicalStats.totalAllocated - historicalStats.totalFreed; var active = historicalStats.allocCount - historicalStats.deallocCount; console.groupCollapsed("[new/delete] Memory Stats - Allocated Diff: ".concat(allocatedDiff, " bytes ") + "(News: ".concat(historicalStats.allocCount, ", Deletes: ").concat(historicalStats.deallocCount, ", Active: ").concat(active, ")")); console.log("[new/delete] Total Allocated: ".concat(historicalStats.totalAllocated, " bytes, ") + "Total Deleted: ".concat(historicalStats.totalFreed, " bytes, Current: ").concat(allocatedDiff, " bytes")); console.log("Historical Summary (new/delete): ".concat(allRecords.size, " total allocations, ").concat(deletedCount, " deleted, ").concat(activeCount, " active")); console.log("Memory: ".concat(totalAllocatedBytes, " bytes allocated; ").concat(notDeallocatedBytes, " bytes not deallocated")); // Group 1: All historical allocations console.groupCollapsed("All Historical New/Delete Allocations (".concat(allRecords.size, " total: ").concat(deletedCount, " deleted, ").concat(activeCount, " active)")); var index = 0; for (var _c = 0, _d = Array.from(allRecords.entries()); _c < _d.length; _c++) { var _e = _d[_c], guid = _e[0], record = _e[1]; var ptrStr = "0x".concat(record.ptr.toString(16)); var status_4 = record.deallocated ? " [DELETED]" : " [ACTIVE]"; var deallocStr = record.deallocated ? " (deleted at ".concat(record.deallocationTimestamp, ")") : ""; console.groupCollapsed("[".concat(index, "] [").concat(record.timestamp, "]: guid=").concat(guid, ", ptr=").concat(ptrStr, ", ").concat(record.size, "bt").concat(status_4).concat(deallocStr)); index++; if (record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); // Group 2: Non-deleted records (potential leaks) if (notDeletedRecords.length > 0) { console.groupCollapsed("Non-Deleted Records (".concat(notDeletedRecords.length, " active allocations; ").concat(notDeallocatedBytes, " bytes)")); for (var _f = 0, notDeletedRecords_4 = notDeletedRecords; _f < notDeletedRecords_4.length; _f++) { var item = notDeletedRecords_4[_f]; var ptrStr = "0x".concat(item.record.ptr.toString(16)); console.groupCollapsed("[".concat(item.index, "] [").concat(item.record.timestamp, "]: guid=").concat(item.record.guid, ", ptr=").concat(ptrStr, ", ").concat(item.record.size, "bt [ACTIVE]")); if (item.record.stackTraceJS) { console.groupCollapsed("JS Stack Trace"); console.log(item.record.stackTraceJS); console.groupEnd(); } console.groupEnd(); } console.groupEnd(); } console.groupEnd(); }; return WasmMemoryDebugHelper; }()); exports.WasmMemoryDebugHelper = WasmMemoryDebugHelper;