Changeset 259418 in webkit


Ignore:
Timestamp:
Apr 2, 2020 2:48:29 PM (4 years ago)
Author:
mark.lam@apple.com
Message:

HeapSnapshotBuilder::analyzeNode() should filter out duplicate cells.
https://bugs.webkit.org/show_bug.cgi?id=209929
<rdar://problem/60974478>

Reviewed by Keith Miller.

HeapSnapshot::finalize() assumes that its list of cells contain no duplicate cells.
HeapSnapshot::appendNode() expects to only be called once for a cell. It doesn't
check for duplicates.

However, with the concurrent GC marker, there’s a racy chance that the same cell
is visited more than once by SlotVisitor, and therefore, SlotVisitor may call
HeapSnapshotBuilder::analyzeNode() (and HeapSnapshot::appendNode()) more than once
for the same cell.

The easiest and cleanest fix for this is to simply keep a HashSet of appended
cells in HeapSnapshotBuilder while it is building the snapshot. We can then use
the hash set to filter out already appended cells, and avoid adding duplicates to
the HeapSnapshot.

  • heap/HeapSnapshotBuilder.cpp:

(JSC::HeapSnapshotBuilder::buildSnapshot):
(JSC::HeapSnapshotBuilder::analyzeNode):

  • heap/HeapSnapshotBuilder.h:
Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r259390 r259418  
     12020-04-02  Mark Lam  <mark.lam@apple.com>
     2
     3        HeapSnapshotBuilder::analyzeNode() should filter out duplicate cells.
     4        https://bugs.webkit.org/show_bug.cgi?id=209929
     5        <rdar://problem/60974478>
     6
     7        Reviewed by Keith Miller.
     8
     9        HeapSnapshot::finalize() assumes that its list of cells contain no duplicate cells.
     10        HeapSnapshot::appendNode() expects to only be called once for a cell.  It doesn't
     11        check for duplicates.
     12
     13        However, with the concurrent GC marker, there’s a racy chance that the same cell
     14        is visited more than once by SlotVisitor, and therefore, SlotVisitor may call
     15        HeapSnapshotBuilder::analyzeNode() (and HeapSnapshot::appendNode()) more than once
     16        for the same cell.
     17
     18        The easiest and cleanest fix for this is to simply keep a HashSet of appended
     19        cells in HeapSnapshotBuilder while it is building the snapshot.  We can then use
     20        the hash set to filter out already appended cells, and avoid adding duplicates to
     21        the HeapSnapshot.
     22
     23        * heap/HeapSnapshotBuilder.cpp:
     24        (JSC::HeapSnapshotBuilder::buildSnapshot):
     25        (JSC::HeapSnapshotBuilder::analyzeNode):
     26        * heap/HeapSnapshotBuilder.h:
     27
    1282020-04-02  Angelos Oikonomopoulos  <angelos@igalia.com>
    229
  • trunk/Source/JavaScriptCore/heap/HeapSnapshotBuilder.cpp

    r257688 r259418  
    11/*
    2  * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7474        m_profiler.setActiveHeapAnalyzer(nullptr);
    7575    }
    76     m_snapshot->finalize();
    77 
     76
     77    {
     78        auto locker = holdLock(m_buildingNodeMutex);
     79        m_appendedCells.clear();
     80        m_snapshot->finalize();
     81    }
    7882    m_profiler.appendSnapshot(WTFMove(m_snapshot));
    7983}
     
    9094
    9195    auto locker = holdLock(m_buildingNodeMutex);
     96    auto addResult = m_appendedCells.add(cell);
     97    if (!addResult.isNewEntry)
     98        return;
    9299    m_snapshot->appendNode(HeapSnapshotNode(cell, getNextObjectIdentifier()));
    93100}
  • trunk/Source/JavaScriptCore/heap/HeapSnapshotBuilder.h

    r248925 r259418  
    11/*
    2  * Copyright (C) 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    155155    HashMap<JSCell*, void*> m_wrappedObjectPointers;
    156156    HashMap<JSCell*, String> m_cellLabels;
     157    HashSet<JSCell*> m_appendedCells;
    157158    SnapshotType m_snapshotType;
    158159};
Note: See TracChangeset for help on using the changeset viewer.