Skip to content

Commit 7771e3e

Browse files
sethbrenithDevtools-frontend LUCI CQ
authored andcommitted
Make 'Reveal in Summary view' work consistently
My recent change caused the 'Reveal in Summary view' command to fail if the object to find was not in the first category with its class name. This CL fixes the problem and adds a regression test. Bug: 357902505 Change-Id: Ice45060c6fbe30b80c95e0a8d91e16d6d1762606 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5967453 Commit-Queue: Seth Brenith <[email protected]> Reviewed-by: Simon Zünd <[email protected]>
1 parent c1b0ea1 commit 7771e3e

File tree

6 files changed

+35
-13
lines changed

6 files changed

+35
-13
lines changed

front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ export abstract class HeapSnapshot {
12721272
// for class keys.
12731273
aggregates = Object.create(null);
12741274
for (const [classKey, aggregate] of aggregatesMap.entries()) {
1275-
const newKey = typeof classKey === 'number' ? (',' + this.strings[classKey]) : classKey;
1275+
const newKey = this.classKeyFromClassKeyInternal(classKey);
12761276
aggregates[newKey] = aggregate;
12771277
}
12781278
if (key) {
@@ -2531,10 +2531,17 @@ export abstract class HeapSnapshot {
25312531
return null;
25322532
}
25332533

2534-
nodeClassName(snapshotObjectId: number): string|null {
2534+
// Converts an internal class key, suitable for categorizing within this
2535+
// snapshot, to a public class key, which can be used in comparisons
2536+
// between multiple snapshots.
2537+
classKeyFromClassKeyInternal(key: string|number): string {
2538+
return typeof key === 'number' ? (',' + this.strings[key]) : key;
2539+
}
2540+
2541+
nodeClassKey(snapshotObjectId: number): string|null {
25352542
const node = this.nodeForSnapshotObjectId(snapshotObjectId);
25362543
if (node) {
2537-
return node.className();
2544+
return this.classKeyFromClassKeyInternal(node.classKeyInternal());
25382545
}
25392546
return null;
25402547
}

front_end/panels/profiler/HeapSnapshotDataGrids.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -831,17 +831,18 @@ export class HeapSnapshotConstructorsDataGrid extends HeapSnapshotViewportDataGr
831831
return null;
832832
}
833833

834-
const className = await this.snapshot.nodeClassName(parseInt(id, 10));
835-
if (!className) {
834+
const classKey = await this.snapshot.nodeClassKey(parseInt(id, 10));
835+
if (!classKey) {
836836
return null;
837837
}
838838

839-
const parent = this.topLevelNodes().find(classNode => classNode.name === className);
839+
const topLevelNodes = this.topLevelNodes() as HeapSnapshotConstructorNode[];
840+
const parent = topLevelNodes.find(classNode => classNode.classKey === classKey);
840841
if (!parent) {
841842
return null;
842843
}
843844

844-
const nodes = await (parent as HeapSnapshotConstructorNode).populateNodeBySnapshotObjectId(parseInt(id, 10));
845+
const nodes = await parent.populateNodeBySnapshotObjectId(parseInt(id, 10));
845846
return nodes.length ? this.revealTreeNode(nodes) : null;
846847
}
847848

front_end/panels/profiler/HeapSnapshotProxy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ export class HeapSnapshotProxy extends HeapSnapshotProxyObject {
314314
return this.callMethodPromise('calculateSnapshotDiff', baseSnapshotId, baseSnapshotAggregates);
315315
}
316316

317-
nodeClassName(snapshotObjectId: number): Promise<string|null> {
318-
return this.callMethodPromise('nodeClassName', snapshotObjectId);
317+
nodeClassKey(snapshotObjectId: number): Promise<string|null> {
318+
return this.callMethodPromise('nodeClassKey', snapshotObjectId);
319319
}
320320

321321
createEdgesProvider(nodeIndex: number): HeapSnapshotProviderProxy {

test/e2e/helpers/memory-helpers.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,12 @@ export async function changeAllocationSampleViewViaDropdown(newPerspective: stri
296296
await dropdown.select(optionValue);
297297
}
298298

299-
export async function focusTableRow(text: string) {
299+
export async function focusTableRowWithName(text: string) {
300300
const row = await waitFor(`//span[text()="${text}"]/ancestor::tr`, undefined, undefined, 'xpath');
301+
await focusTableRow(row);
302+
}
303+
304+
export async function focusTableRow(row: puppeteer.ElementHandle<Element>) {
301305
// Click in a numeric cell, to avoid accidentally clicking a link.
302306
const cell = await waitFor('.numeric-column', row);
303307
await clickElement(cell);

test/e2e/memory/memory_test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
expandFocusedRow,
3030
findSearchResult,
3131
focusTableRow,
32+
focusTableRowWithName,
3233
getAddedCountFromComparisonRow,
3334
getAddedCountFromComparisonRowWithName,
3435
getCategoryRow,
@@ -433,12 +434,12 @@ describe('The Memory Panel', function() {
433434
await setSearchFilter('Retainer');
434435
await waitForSearchResultNumber(4);
435436
await findSearchResult('Retainer()');
436-
await focusTableRow('Retainer()');
437+
await focusTableRowWithName('Retainer()');
437438
await expandFocusedRow();
438-
await focusTableRow('customProperty');
439+
await focusTableRowWithName('customProperty');
439440
const sizesForSet = await getSizesFromSelectedRow();
440441
await expandFocusedRow();
441-
await focusTableRow('(internal array)[]');
442+
await focusTableRowWithName('(internal array)[]');
442443
const sizesForBackingStorage = await getSizesFromSelectedRow();
443444
return {sizesForSet, sizesForBackingStorage};
444445
}
@@ -582,7 +583,14 @@ describe('The Memory Panel', function() {
582583
let rows = await waitForMany('tr.data-grid-data-grid-node', 2);
583584
assert.strictEqual(30, await getCountFromCategoryRow(rows[0]));
584585
assert.strictEqual(3, await getCountFromCategoryRow(rows[1]));
586+
await focusTableRow(rows[0]);
587+
await expandFocusedRow();
585588
const {frontend, target} = await getBrowserAndPages();
589+
await frontend.keyboard.press('ArrowDown');
590+
await clickOnContextMenuForRetainer('x', 'Reveal in Summary view');
591+
await waitUntilRetainerChainSatisfies(
592+
retainerChain => retainerChain.length > 0 && retainerChain[0].propertyName === 'a');
593+
586594
await target.bringToFront();
587595
await target.click('button#update');
588596
await frontend.bringToFront();

test/e2e/resources/memory/duplicated-names.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ <h1>Memory Panel (Heap profiler) Test</h1>
1919
for (let i = 0; i < 30; ++i) {
2020
holder.d.push(makeObject());
2121
}
22+
holder.a.x = holder.d[0];
23+
holder.d[0].x = [1, 2, 3];
2224
document.getElementById('update').addEventListener('click', function () {
2325
holder.b = new DuplicatedClassName();
2426
holder.e = new DuplicatedClassName();

0 commit comments

Comments
 (0)