Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(845)

Side by Side Diff: Source/devtools/front_end/HeapSnapshotView.js

Issue 14639004: DevTools: [TrackingHeapProfiler] Provide a chart with living heap date at recording time. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | Source/devtools/front_end/ProfilesPanel.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 * @extends {WebInspector.ProfileType} 768 * @extends {WebInspector.ProfileType}
769 * @implements {HeapProfilerAgent.Dispatcher} 769 * @implements {HeapProfilerAgent.Dispatcher}
770 */ 770 */
771 WebInspector.HeapSnapshotProfileType = function() 771 WebInspector.HeapSnapshotProfileType = function()
772 { 772 {
773 WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.Typ eId, WebInspector.UIString("Take Heap Snapshot")); 773 WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.Typ eId, WebInspector.UIString("Take Heap Snapshot"));
774 InspectorBackend.registerHeapProfilerDispatcher(this); 774 InspectorBackend.registerHeapProfilerDispatcher(this);
775 } 775 }
776 776
777 WebInspector.HeapSnapshotProfileType.TypeId = "HEAP"; 777 WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
778 WebInspector.HeapSnapshotProfileType.HeapStatsUpdate = "HeapStatsUpdate";
778 779
779 WebInspector.HeapSnapshotProfileType.prototype = { 780 WebInspector.HeapSnapshotProfileType.prototype = {
780 /** 781 /**
781 * @override 782 * @override
782 * @return {string} 783 * @return {string}
783 */ 784 */
784 fileExtension: function() 785 fileExtension: function()
785 { 786 {
786 return ".heapsnapshot"; 787 return ".heapsnapshot";
787 }, 788 },
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 this._lastUpdatedIndex = index; 864 this._lastUpdatedIndex = index;
864 }, 865 },
865 866
866 /** 867 /**
867 * @override 868 * @override
868 * @param {number} lastSeenObjectId 869 * @param {number} lastSeenObjectId
869 * @param {number} timestamp 870 * @param {number} timestamp
870 */ 871 */
871 lastSeenObjectId: function(lastSeenObjectId, timestamp) 872 lastSeenObjectId: function(lastSeenObjectId, timestamp)
872 { 873 {
874 if (!this._profileSamples)
875 return;
876
873 this._profileSamples.ids[this._currentIndex] = lastSeenObjectId; 877 this._profileSamples.ids[this._currentIndex] = lastSeenObjectId;
874 this._profileSamples.timestamps[this._currentIndex] = timestamp; 878 this._profileSamples.timestamps[this._currentIndex] = timestamp;
875 if (!this._profileSamples.max[this._currentIndex]) { 879 if (!this._profileSamples.max[this._currentIndex]) {
876 this._profileSamples.max[this._currentIndex] = 0; 880 this._profileSamples.max[this._currentIndex] = 0;
877 this._profileSamples.sizes[this._currentIndex] = 0; 881 this._profileSamples.sizes[this._currentIndex] = 0;
878 } 882 }
879 ++this._currentIndex; 883 ++this._currentIndex;
884 this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.HeapS tatsUpdate, this._profileSamples);
880 }, 885 },
881 886
882 get treeItemTitle() 887 get treeItemTitle()
883 { 888 {
884 return WebInspector.UIString("HEAP SNAPSHOTS"); 889 return WebInspector.UIString("HEAP SNAPSHOTS");
885 }, 890 },
886 891
887 get description() 892 get description()
888 { 893 {
889 return WebInspector.UIString("Heap snapshot profiles show memory distrib ution among your page's JavaScript objects and related DOM nodes."); 894 return WebInspector.UIString("Heap snapshot profiles show memory distrib ution among your page's JavaScript objects and related DOM nodes.");
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 WebInspector.TrackingHeapSnapshotProfileType = function(profilesPanel, profileTy pe) 1011 WebInspector.TrackingHeapSnapshotProfileType = function(profilesPanel, profileTy pe)
1007 { 1012 {
1008 WebInspector.ProfileType.call(this, WebInspector.TrackingHeapSnapshotProfile Type.TypeId, WebInspector.UIString("Track Allocations")); 1013 WebInspector.ProfileType.call(this, WebInspector.TrackingHeapSnapshotProfile Type.TypeId, WebInspector.UIString("Track Allocations"));
1009 this._profilesPanel = profilesPanel; 1014 this._profilesPanel = profilesPanel;
1010 this._parentType = profileType; 1015 this._parentType = profileType;
1011 } 1016 }
1012 1017
1013 WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD"; 1018 WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD";
1014 1019
1015 WebInspector.TrackingHeapSnapshotProfileType.prototype = { 1020 WebInspector.TrackingHeapSnapshotProfileType.prototype = {
1021 hasTemporaryView: function()
1022 {
1023 return true;
1024 },
1025
1016 get buttonTooltip() 1026 get buttonTooltip()
1017 { 1027 {
1018 return this._recording ? WebInspector.UIString("Stop recording heap prof ile.") : WebInspector.UIString("Start recording heap profile."); 1028 return this._recording ? WebInspector.UIString("Stop recording heap prof ile.") : WebInspector.UIString("Start recording heap profile.");
1019 }, 1029 },
1020 1030
1021 /** 1031 /**
1022 * @override 1032 * @override
1023 * @return {boolean} 1033 * @return {boolean}
1024 */ 1034 */
1025 isInstantProfile: function() 1035 isInstantProfile: function()
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 { 1113 {
1104 return new WebInspector.ProfileSidebarTreeElement(this, WebInspector.UIS tring("Snapshot %d"), "heap-snapshot-sidebar-tree-item"); 1114 return new WebInspector.ProfileSidebarTreeElement(this, WebInspector.UIS tring("Snapshot %d"), "heap-snapshot-sidebar-tree-item");
1105 }, 1115 },
1106 1116
1107 /** 1117 /**
1108 * @override 1118 * @override
1109 * @param {!WebInspector.ProfilesPanel} profilesPanel 1119 * @param {!WebInspector.ProfilesPanel} profilesPanel
1110 */ 1120 */
1111 createView: function(profilesPanel) 1121 createView: function(profilesPanel)
1112 { 1122 {
1123 if (this._profileType.id === WebInspector.TrackingHeapSnapshotProfileTyp e.TypeId) {
1124 var view = new WebInspector.HeapTrackingOverviewGrid(this);
1125 this._profileType._parentType.addEventListener(WebInspector.HeapSnap shotProfileType.HeapStatsUpdate, view._onHeapStatsUpdate.bind(view));
1126 return view;
1127 }
1113 return new WebInspector.HeapSnapshotView(profilesPanel, this); 1128 return new WebInspector.HeapSnapshotView(profilesPanel, this);
1114 }, 1129 },
1115 1130
1116 /** 1131 /**
1117 * @override 1132 * @override
1118 * @param {function(WebInspector.HeapSnapshotProxy):void} callback 1133 * @param {function(WebInspector.HeapSnapshotProxy):void} callback
1119 */ 1134 */
1120 load: function(callback) 1135 load: function(callback)
1121 { 1136 {
1122 if (this._snapshotProxy) { 1137 if (this._snapshotProxy) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 break; 1345 break;
1331 default: 1346 default:
1332 this._snapshotHeader.sidebarElement.subtitle = WebInspector.UIString ("'%s' error %d", reader.fileName(), e.target.error.code); 1347 this._snapshotHeader.sidebarElement.subtitle = WebInspector.UIString ("'%s' error %d", reader.fileName(), e.target.error.code);
1333 } 1348 }
1334 } 1349 }
1335 } 1350 }
1336 1351
1337 /** 1352 /**
1338 * @constructor 1353 * @constructor
1339 * @extends {WebInspector.View} 1354 * @extends {WebInspector.View}
1340 * @param {!WebInspector.HeapProfileHeader} heapProfileHeader 1355 * @param {?WebInspector.HeapProfileHeader} heapProfileHeader
1341 */ 1356 */
1342 WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader) 1357 WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader)
1343 { 1358 {
1344 WebInspector.View.call(this); 1359 WebInspector.View.call(this);
1345 this.registerRequiredCSS("flameChart.css"); 1360 this.registerRequiredCSS("flameChart.css");
1346 this.element.id = "heap-recording-view"; 1361 this.element.id = "heap-recording-view";
1347 1362
1348 this._overviewContainer = this.element.createChild("div", "overview-containe r"); 1363 this._overviewContainer = this.element.createChild("div", "overview-containe r");
1349 this._overviewGrid = new WebInspector.OverviewGrid("heap-recording"); 1364 this._overviewGrid = new WebInspector.OverviewGrid("heap-recording");
1350 this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-r ecording-overview-canvas"); 1365 this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-r ecording-overview-canvas");
1351 this._overviewContainer.appendChild(this._overviewGrid.element); 1366 this._overviewContainer.appendChild(this._overviewGrid.element);
1352 this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.Overvie wCalculator(); 1367 this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.Overvie wCalculator();
1353 this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowC hanged, this._onWindowChanged, this); 1368 this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowC hanged, this._onWindowChanged, this);
1354 1369
1355 this._profileSamples = heapProfileHeader._profileSamples; 1370 this._minimumTimeDelta = 60000;
1356 var timestamps = this._profileSamples.timestamps; 1371 if (heapProfileHeader && heapProfileHeader._profileSamples) {
1357 var startTime = timestamps[0]; 1372 this._profileSamples = heapProfileHeader._profileSamples;
1358 this._totalTime = timestamps[timestamps.length - 1] - startTime; 1373 var timestamps = this._profileSamples.timestamps;
1374 var startTime = timestamps[0];
1375 this._totalTime = timestamps[timestamps.length - 1] - startTime;
1376 } else
1377 this._resetTrackingData();
1359 this._windowLeft = 0.0; 1378 this._windowLeft = 0.0;
1360 this._windowRight = 1.0; 1379 this._windowRight = 1.0;
1361 } 1380 }
1362 1381
1363 WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged"; 1382 WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged";
1364 1383
1365 WebInspector.HeapTrackingOverviewGrid.prototype = { 1384 WebInspector.HeapTrackingOverviewGrid.prototype = {
1385 _resetTrackingData: function(profileSamples)
1386 {
1387 this._totalTime = this._minimumTimeDelta;
1388 this._profileSamples = profileSamples;
1389 },
1390
1366 /** 1391 /**
1367 * @param {number} width 1392 * @param {number} width
1368 * @param {number} height 1393 * @param {number} height
1369 */ 1394 */
1370 _drawOverviewCanvas: function(width, height) 1395 _drawOverviewCanvas: function(width, height)
1371 { 1396 {
1397 if (!this._profileSamples)
1398 return;
1372 var sizes = this._profileSamples.sizes; 1399 var sizes = this._profileSamples.sizes;
1373 var usedSizes = this._profileSamples.max; 1400 var usedSizes = this._profileSamples.max;
1374 var timestamps = this._profileSamples.timestamps; 1401 var timestamps = this._profileSamples.timestamps;
1375 1402
1376 var scaleFactor = width / this._totalTime; 1403 var scaleFactor = width / this._totalTime;
1377 var maxUsedSize = 0; 1404 var maxUsedSize = 0;
1378 var currentX = 0; 1405 var currentX = 0;
1379 /** 1406 /**
1380 * @param {Array.<number>} sizes 1407 * @param {Array.<number>} sizes
1381 * @param {function(number, number):void} callback 1408 * @param {function(number, number):void} callback
1382 */ 1409 */
1383 function aggregateAndCall(sizes, callback) 1410 function aggregateAndCall(sizes, callback)
1384 { 1411 {
1385 var size = 0; 1412 var size = 0;
1386 var currentX = 0; 1413 var currentX = 0;
1387 for (var i = 1; i < timestamps.length; ++i) { 1414 for (var i = 1; i < timestamps.length; ++i) {
1388 var x = Math.floor((timestamps[i] - startTime) * scaleFactor) ; 1415 var x = Math.floor((timestamps[i] - startTime) * scaleFactor);
1389 if (x !== currentX) { 1416 if (x !== currentX) {
1390 if (size) 1417 if (size)
1391 callback(currentX, size); 1418 callback(currentX, size);
1392 size = 0; 1419 size = 0;
1393 currentX = x; 1420 currentX = x;
1394 } 1421 }
1395 size += sizes[i]; 1422 size += sizes[i];
1396 } 1423 }
1397 callback(currentX, size); 1424 callback(currentX, size);
1398 } 1425 }
1399 1426
1400 /** 1427 /**
1401 * @param {number} x 1428 * @param {number} x
1402 * @param {number} size 1429 * @param {number} size
1403 */ 1430 */
1404 function maxUsedSizeCallback(x, size) 1431 function maxUsedSizeCallback(x, size)
1405 { 1432 {
1406 maxUsedSize = Math.max(maxUsedSize, size); 1433 maxUsedSize = Math.max(maxUsedSize, size);
1407 } 1434 }
1408 1435
1409 aggregateAndCall(usedSizes, maxUsedSizeCallback); 1436 aggregateAndCall(usedSizes, maxUsedSizeCallback);
1410 1437
1411 this._overviewCanvas.width = width * window.devicePixelRatio; 1438 this._overviewCanvas.width = width * window.devicePixelRatio;
1412 this._overviewCanvas.height = height * window.devicePixelRatio; 1439 this._overviewCanvas.height = height * window.devicePixelRatio;
1413 this._overviewCanvas.style.width = width + "px"; 1440 this._overviewCanvas.style.width = width + "px";
1414 this._overviewCanvas.style.height = height + "px"; 1441 this._overviewCanvas.style.height = height + "px";
1415 var yScaleFactor = height / (maxUsedSize * 1.1); 1442 var yScaleFactor = height / (maxUsedSize * 1.1);
1416 var startTime = timestamps[0]; 1443 var startTime = timestamps[0];
1444 var endTime = timestamps[timestamps.length - 1];
1417 1445
1418 var context = this._overviewCanvas.getContext("2d"); 1446 var context = this._overviewCanvas.getContext("2d");
1419 context.scale(window.devicePixelRatio, window.devicePixelRatio); 1447 context.scale(window.devicePixelRatio, window.devicePixelRatio);
1420 1448
1449 context.beginPath();
1450 context.lineWidth = 2;
1451 context.strokeStyle = "rgba(192, 192, 192, 0.6)";
1452 var currentX = Math.floor((endTime - startTime) * scaleFactor);
1453 context.moveTo(currentX, height - 1);
1454 context.lineTo(currentX, 0);
1455 context.stroke();
1456 context.closePath();
1457
1421 /** 1458 /**
1422 * @param {number} x 1459 * @param {number} x
1423 * @param {number} size 1460 * @param {number} size
1424 */ 1461 */
1425 function drawBarCallback(x, size) 1462 function drawBarCallback(x, size)
1426 { 1463 {
1427 context.moveTo(x, height - 1); 1464 context.moveTo(x, height - 1);
1428 context.lineTo(x, Math.round(height - size * yScaleFactor - 1)); 1465 context.lineTo(x, Math.round(height - size * yScaleFactor - 1));
1429 } 1466 }
1430 1467
(...skipping 17 matching lines...) Expand all
1448 this._updateOverviewCanvas = true; 1485 this._updateOverviewCanvas = true;
1449 this._scheduleUpdate(); 1486 this._scheduleUpdate();
1450 }, 1487 },
1451 1488
1452 _onWindowChanged: function() 1489 _onWindowChanged: function()
1453 { 1490 {
1454 if (!this._updateGridTimerId) 1491 if (!this._updateGridTimerId)
1455 this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10 ); 1492 this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10 );
1456 }, 1493 },
1457 1494
1495 _onHeapStatsUpdate: function(event)
1496 {
1497 this._profileSamples = event.data;
1498 var timestamps = this._profileSamples.timestamps;
1499 if (this._totalTime < timestamps[timestamps.length - 1] - timestamps[0])
1500 this._totalTime *= 2;
1501 this._scheduleUpdate();
1502 },
1503
1458 _scheduleUpdate: function() 1504 _scheduleUpdate: function()
1459 { 1505 {
1460 if (this._updateTimerId) 1506 if (this._updateTimerId)
1461 return; 1507 return;
1462 this._updateTimerId = setTimeout(this.update.bind(this), 10); 1508 this._updateTimerId = setTimeout(this.update.bind(this), 10);
1463 }, 1509 },
1464 1510
1465 _updateBoundaries: function() 1511 _updateBoundaries: function()
1466 { 1512 {
1467 this._windowLeft = this._overviewGrid.windowLeft(); 1513 this._windowLeft = this._overviewGrid.windowLeft();
1468 this._windowRight = this._overviewGrid.windowRight(); 1514 this._windowRight = this._overviewGrid.windowRight();
1469 this._windowWidth = this._windowRight - this._windowLeft; 1515 this._windowWidth = this._windowRight - this._windowLeft;
1470 }, 1516 },
1471 1517
1472 /** 1518 /**
1473 * @param {boolean} updateOverviewCanvas 1519 * @param {boolean} updateOverviewCanvas
1474 */ 1520 */
1475 update: function(updateOverviewCanvas) 1521 update: function(updateOverviewCanvas)
1476 { 1522 {
1477 this._updateTimerId = null; 1523 this._updateTimerId = null;
1478 this._updateBoundaries(); 1524 this._updateBoundaries();
1479 this._overviewCalculator._updateBoundaries(this); 1525 this._overviewCalculator._updateBoundaries(this);
1480 this._overviewGrid.updateDividers(this._overviewCalculator); 1526 this._overviewGrid.updateDividers(this._overviewCalculator);
1481 if (this._updateOverviewCanvas || updateOverviewCanvas) { 1527 this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._over viewContainer.clientHeight - 20);
1482 this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._ overviewContainer.clientHeight - 20);
1483 this._updateOverviewCanvas = false;
1484 }
1485 }, 1528 },
1486 1529
1487 _updateGrid: function() 1530 _updateGrid: function()
1488 { 1531 {
1532 if (!this._profileSamples)
1533 return;
1489 this._updateGridTimerId = 0; 1534 this._updateGridTimerId = 0;
1490 this._updateBoundaries(); 1535 this._updateBoundaries();
1491 var ids = this._profileSamples.ids; 1536 var ids = this._profileSamples.ids;
1492 var timestamps = this._profileSamples.timestamps; 1537 var timestamps = this._profileSamples.timestamps;
1493 var sizes = this._profileSamples.sizes; 1538 var sizes = this._profileSamples.sizes;
1494 var startTime = timestamps[0]; 1539 var startTime = timestamps[0];
1495 var finishTime = timestamps[timestamps.length - 1]; 1540 var finishTime = timestamps[timestamps.length - 1];
1496 var timeRange = finishTime - startTime; 1541 var timeRange = finishTime - startTime;
1497 var timeLeft = startTime + timeRange * this._windowLeft; 1542 var timeLeft = startTime + timeRange * this._windowLeft;
1498 var timeRight = startTime + timeRange * this._windowRight; 1543 var timeRight = startTime + timeRange * this._windowRight;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 zeroTime: function() 1609 zeroTime: function()
1565 { 1610 {
1566 return this._minimumBoundaries; 1611 return this._minimumBoundaries;
1567 }, 1612 },
1568 1613
1569 boundarySpan: function() 1614 boundarySpan: function()
1570 { 1615 {
1571 return this._maximumBoundaries - this._minimumBoundaries; 1616 return this._maximumBoundaries - this._minimumBoundaries;
1572 } 1617 }
1573 } 1618 }
OLDNEW
« no previous file with comments | « no previous file | Source/devtools/front_end/ProfilesPanel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698