Changeset 213675 in webkit for trunk/Source/JavaScriptCore/tools/HeapVerifier.cpp
- Timestamp:
- Mar 9, 2017, 2:39:09 PM (8 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/tools/HeapVerifier.cpp
r213674 r213675 67 67 } 68 68 69 struct Gather LiveObjFunctor : MarkedBlock::CountFunctor {70 Gather LiveObjFunctor(LiveObjectList& list)69 struct GatherCellFunctor : MarkedBlock::CountFunctor { 70 GatherCellFunctor(CellList& list) 71 71 : m_list(list) 72 72 { 73 ASSERT(!list.live Objects.size());73 ASSERT(!list.liveCells.size()); 74 74 } 75 75 76 76 inline void visit(JSCell* cell) 77 77 { 78 if (!cell->isObject()) 79 return; 80 LiveObjectData data(asObject(cell)); 81 m_list.liveObjects.append(data); 78 CellProfile profile(cell); 79 m_list.liveCells.append(profile); 82 80 } 83 81 … … 87 85 // FIXME: This const_cast exists because this isn't a C++ lambda. 88 86 // https://bugs.webkit.org/show_bug.cgi?id=159644 89 const_cast<Gather LiveObjFunctor*>(this)->visit(static_cast<JSCell*>(cell));87 const_cast<GatherCellFunctor*>(this)->visit(static_cast<JSCell*>(cell)); 90 88 } 91 89 return IterationStatus::Continue; 92 90 } 93 91 94 LiveObjectList& m_list;92 CellList& m_list; 95 93 }; 96 94 97 void HeapVerifier::gatherLive Objects(HeapVerifier::Phase phase)95 void HeapVerifier::gatherLiveCells(HeapVerifier::Phase phase) 98 96 { 99 97 Heap* heap = m_heap; 100 LiveObjectList& list = *liveObjectListForGathering(phase);98 CellList& list = *cellListForGathering(phase); 101 99 102 100 HeapIterationScope iterationScope(*heap); 103 101 list.reset(); 104 Gather LiveObjFunctor functor(list);102 GatherCellFunctor functor(list); 105 103 heap->m_objectSpace.forEachLiveCell(iterationScope, functor); 106 104 } 107 105 108 LiveObjectList* HeapVerifier::liveObjectListForGathering(HeapVerifier::Phase phase)106 CellList* HeapVerifier::cellListForGathering(HeapVerifier::Phase phase) 109 107 { 110 108 switch (phase) { … … 115 113 case Phase::BeforeGC: 116 114 case Phase::AfterGC: 117 // We should not be gathering live objects during these phases.115 // We should not be gathering live cells during these phases. 118 116 break; 119 117 } … … 122 120 } 123 121 124 static void trimDead ObjectsFromList(HashSet<JSObject*>& knownLiveSet, LiveObjectList& list)125 { 126 if (!list.hasLive Objects)122 static void trimDeadCellsFromList(HashSet<JSCell*>& knownLiveSet, CellList& list) 123 { 124 if (!list.hasLiveCells) 127 125 return; 128 126 129 size_t live ObjectsFound = 0;130 for (auto& objData : list.liveObjects) {131 if ( objData.isConfirmedDead)132 continue; // Don't "resurrect" known dead objects.133 if (!knownLiveSet.contains( objData.obj)) {134 objData.isConfirmedDead = true;127 size_t liveCellsFound = 0; 128 for (auto& cellProfile : list.liveCells) { 129 if (cellProfile.isConfirmedDead) 130 continue; // Don't "resurrect" known dead cells. 131 if (!knownLiveSet.contains(cellProfile.cell)) { 132 cellProfile.isConfirmedDead = true; 135 133 continue; 136 134 } 137 live ObjectsFound++;138 } 139 list.hasLive Objects = !!liveObjectsFound;140 } 141 142 void HeapVerifier::trimDead Objects()143 { 144 HashSet<JS Object*> knownLiveSet;145 146 LiveObjectList& after = currentCycle().after;147 for (auto& objData : after.liveObjects)148 knownLiveSet.add( objData.obj);149 150 trimDead ObjectsFromList(knownLiveSet, currentCycle().before);135 liveCellsFound++; 136 } 137 list.hasLiveCells = !!liveCellsFound; 138 } 139 140 void HeapVerifier::trimDeadCells() 141 { 142 HashSet<JSCell*> knownLiveSet; 143 144 CellList& after = currentCycle().after; 145 for (auto& cellProfile : after.liveCells) 146 knownLiveSet.add(cellProfile.cell); 147 148 trimDeadCellsFromList(knownLiveSet, currentCycle().before); 151 149 152 150 for (int i = -1; i > -m_numberOfCycles; i--) { 153 trimDead ObjectsFromList(knownLiveSet, cycleForIndex(i).before);154 trimDead ObjectsFromList(knownLiveSet, cycleForIndex(i).after);155 } 156 } 157 158 bool HeapVerifier::verifyButterflyIsInStorageSpace(Phase, LiveObjectList&)151 trimDeadCellsFromList(knownLiveSet, cycleForIndex(i).before); 152 trimDeadCellsFromList(knownLiveSet, cycleForIndex(i).after); 153 } 154 } 155 156 bool HeapVerifier::verifyButterflyIsInStorageSpace(Phase, CellList&) 159 157 { 160 158 // FIXME: Make this work again. https://bugs.webkit.org/show_bug.cgi?id=161752 … … 169 167 } 170 168 171 void HeapVerifier::report Object(LiveObjectData& objData, int cycleIndex, HeapVerifier::GCCycle& cycle, LiveObjectList& list)172 { 173 JS Object* obj = objData.obj;174 175 if ( objData.isConfirmedDead) {176 dataLogF("FOUND dead obj%p in GC[%d] %s list '%s'\n",177 obj, cycleIndex, collectionScopeName(cycle.scope), list.name);169 void HeapVerifier::reportCell(CellProfile& cellProfile, int cycleIndex, HeapVerifier::GCCycle& cycle, CellList& list) 170 { 171 JSCell* cell = cellProfile.cell; 172 173 if (cellProfile.isConfirmedDead) { 174 dataLogF("FOUND dead cell %p in GC[%d] %s list '%s'\n", 175 cell, cycleIndex, collectionScopeName(cycle.scope), list.name); 178 176 return; 179 177 } 180 178 181 Structure* structure = obj->structure(); 182 Butterfly* butterfly = obj->butterfly(); 183 void* butterflyBase = butterfly->base(structure); 184 185 dataLogF("FOUND obj %p type '%s' butterfly %p (base %p) in GC[%d] %s list '%s'\n", 186 obj, structure->classInfo()->className, 187 butterfly, butterflyBase, 188 cycleIndex, collectionScopeName(cycle.scope), list.name); 189 } 190 191 void HeapVerifier::checkIfRecorded(JSObject* obj) 179 if (cell->isObject()) { 180 JSObject* object = static_cast<JSObject*>(cell); 181 Structure* structure = object->structure(); 182 Butterfly* butterfly = object->butterfly(); 183 void* butterflyBase = butterfly->base(structure); 184 185 dataLogF("FOUND object %p type '%s' butterfly %p (base %p) in GC[%d] %s list '%s'\n", 186 object, structure->classInfo()->className, 187 butterfly, butterflyBase, 188 cycleIndex, collectionScopeName(cycle.scope), list.name); 189 } else { 190 Structure* structure = cell->structure(); 191 dataLogF("FOUND cell %p type '%s' in GC[%d] %s list '%s'\n", 192 cell, structure->classInfo()->className, 193 cycleIndex, collectionScopeName(cycle.scope), list.name); 194 } 195 } 196 197 void HeapVerifier::checkIfRecorded(JSCell* cell) 192 198 { 193 199 bool found = false; … … 195 201 for (int cycleIndex = 0; cycleIndex > -m_numberOfCycles; cycleIndex--) { 196 202 GCCycle& cycle = cycleForIndex(cycleIndex); 197 LiveObjectList& beforeList = cycle.before;198 LiveObjectList& afterList = cycle.after;199 200 LiveObjectData* objData;201 objData = beforeList.findObject(obj);202 if ( objData) {203 report Object(*objData, cycleIndex, cycle, beforeList);203 CellList& beforeList = cycle.before; 204 CellList& afterList = cycle.after; 205 206 CellProfile* profile; 207 profile = beforeList.findCell(cell); 208 if (profile) { 209 reportCell(*profile, cycleIndex, cycle, beforeList); 204 210 found = true; 205 211 } 206 objData = afterList.findObject(obj);207 if ( objData) {208 report Object(*objData, cycleIndex, cycle, afterList);212 profile = afterList.findCell(cell); 213 if (profile) { 214 reportCell(*profile, cycleIndex, cycle, afterList); 209 215 found = true; 210 216 } … … 212 218 213 219 if (!found) 214 dataLogF(" obj %p NOT FOUND\n", obj);220 dataLogF("cell %p NOT FOUND\n", cell); 215 221 } 216 222
Note:
See TracChangeset
for help on using the changeset viewer.