Changeset 119633 in webkit
- Timestamp:
- Jun 6, 2012 4:11:09 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r119623 r119633 1 2012-06-06 Michael Saboff <msaboff@apple.com> 2 3 ENH: Add Logging to GC Marking Phase 4 https://bugs.webkit.org/show_bug.cgi?id=88364 5 6 Reviewed by Filip Pizlo. 7 8 Log GC marking to stderr or a file. The logging in controlled 9 with the define ENABLE_OBJECT_MARK_LOGGING in wtf/Platform.h. 10 If DATA_LOG_TO_FILE in wtf/DataLog.cpp is set to 1, output is 11 logged to a file otherwise it is logged to stderr. 12 13 When logging is enabled, the GC is built single threaded since the 14 log output from the various threads isn't buffered and output in a 15 thread safe manner. 16 17 * heap/Heap.cpp: 18 (JSC::Heap::markRoots): 19 * heap/MarkStack.cpp: 20 (JSC::MarkStackThreadSharedData::resetChildren): 21 (JSC::MarkStackThreadSharedData::childVisitCount): 22 (JSC::MarkStackThreadSharedData::markingThreadMain): 23 (JSC::MarkStackThreadSharedData::markingThreadStartFunc): 24 (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): 25 (JSC::MarkStackThreadSharedData::reset): 26 * heap/MarkStack.h: 27 (MarkStackThreadSharedData): 28 (MarkStack): 29 (JSC::MarkStack::sharedData): 30 (JSC::MarkStack::resetChildCount): 31 (JSC::MarkStack::childCount): 32 (JSC::MarkStack::incrementChildCount): 33 * runtime/JSArray.cpp: 34 (JSC::JSArray::visitChildren): 35 * runtime/JSCell.cpp: 36 (JSC::JSCell::className): 37 * runtime/JSCell.h: 38 (JSCell): 39 (JSC::JSCell::visitChildren): 40 * runtime/JSString.cpp: 41 (JSC::JSString::visitChildren): 42 * runtime/JSString.h: 43 (JSString): 44 * runtime/Structure.h: 45 (JSC::MarkStack::internalAppend): 46 1 47 2012-06-06 Gavin Barraclough <barraclough@apple.com> 2 48 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r119518 r119633 422 422 ASSERT(isValidThreadState(m_globalData)); 423 423 424 #if ENABLE(OBJECT_MARK_LOGGING) 425 double gcStartTime = WTF::currentTime(); 426 #endif 427 424 428 void* dummy; 425 429 … … 485 489 { 486 490 GCPHASE(VisitMachineRoots); 491 MARK_LOG_ROOT(visitor, "C++ Stack"); 487 492 visitor.append(machineThreadRoots); 488 493 visitor.donateAndDrain(); … … 490 495 { 491 496 GCPHASE(VisitRegisterFileRoots); 497 MARK_LOG_ROOT(visitor, "Register File"); 492 498 visitor.append(registerFileRoots); 493 499 visitor.donateAndDrain(); … … 496 502 { 497 503 GCPHASE(VisitScratchBufferRoots); 504 MARK_LOG_ROOT(visitor, "Scratch Buffers"); 498 505 visitor.append(scratchBufferRoots); 499 506 visitor.donateAndDrain(); … … 502 509 { 503 510 GCPHASE(VisitProtectedObjects); 511 MARK_LOG_ROOT(visitor, "Protected Objects"); 504 512 markProtectedObjects(heapRootVisitor); 505 513 visitor.donateAndDrain(); … … 507 515 { 508 516 GCPHASE(VisitTempSortVectors); 517 MARK_LOG_ROOT(visitor, "Temp Sort Vectors"); 509 518 markTempSortVectors(heapRootVisitor); 510 519 visitor.donateAndDrain(); … … 514 523 GCPHASE(MarkingArgumentBuffers); 515 524 if (m_markListSet && m_markListSet->size()) { 525 MARK_LOG_ROOT(visitor, "Argument Buffers"); 516 526 MarkedArgumentBuffer::markLists(heapRootVisitor, *m_markListSet); 517 527 visitor.donateAndDrain(); … … 520 530 if (m_globalData->exception) { 521 531 GCPHASE(MarkingException); 532 MARK_LOG_ROOT(visitor, "Exceptions"); 522 533 heapRootVisitor.visit(&m_globalData->exception); 523 534 visitor.donateAndDrain(); … … 526 537 { 527 538 GCPHASE(VisitStrongHandles); 539 MARK_LOG_ROOT(visitor, "Strong Handles"); 528 540 m_handleSet.visitStrongHandles(heapRootVisitor); 529 541 visitor.donateAndDrain(); … … 532 544 { 533 545 GCPHASE(HandleStack); 546 MARK_LOG_ROOT(visitor, "Handle Stack"); 534 547 m_handleStack.visit(heapRootVisitor); 535 548 visitor.donateAndDrain(); … … 538 551 { 539 552 GCPHASE(TraceCodeBlocks); 553 MARK_LOG_ROOT(visitor, "Trace Code Blocks"); 540 554 m_dfgCodeBlocks.traceMarkedCodeBlocks(visitor); 541 555 visitor.donateAndDrain(); … … 554 568 { 555 569 GCPHASE(VisitingLiveWeakHandles); 570 MARK_LOG_ROOT(visitor, "Live Weak Handles"); 556 571 while (true) { 557 572 m_objectSpace.visitWeakSets(heapRootVisitor); … … 572 587 573 588 visitor.doneCopying(); 589 #if ENABLE(OBJECT_MARK_LOGGING) 590 size_t visitCount = visitor.visitCount(); 591 #if ENABLE(PARALLEL_GC) 592 visitCount += m_sharedData.childVisitCount(); 593 #endif 594 MARK_LOG_MESSAGE2("\nNumber of live Objects after full GC %lu, took %.6f secs\n", visitCount, WTF::currentTime() - gcStartTime); 595 #endif 596 574 597 visitor.reset(); 575 598 m_sharedData.reset(); 599 #if ENABLE(PARALLEL_GC) 600 m_sharedData.resetChildren(); 601 #endif 576 602 m_storageSpace.doneCopying(); 577 603 -
trunk/Source/JavaScriptCore/heap/MarkStack.cpp
r117013 r119633 37 37 #include "ScopeChain.h" 38 38 #include "Structure.h" 39 #include "UString.h" 39 40 #include "WriteBarrier.h" 40 41 #include <wtf/DataLog.h> … … 220 221 221 222 #if ENABLE(PARALLEL_GC) 222 void MarkStackThreadSharedData::markingThreadMain() 223 void MarkStackThreadSharedData::resetChildren() 224 { 225 for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) 226 m_markingThreadsMarkStack[i]->reset(); 227 } 228 229 size_t MarkStackThreadSharedData::childVisitCount() 230 { 231 unsigned long result = 0; 232 for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) 233 result += m_markingThreadsMarkStack[i]->visitCount(); 234 return result; 235 } 236 237 void MarkStackThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor) 223 238 { 224 239 WTF::registerGCThread(); 225 240 { 226 SlotVisitor slotVisitor(*this); 227 ParallelModeEnabler enabler(slotVisitor); 228 slotVisitor.drainFromShared(SlotVisitor::SlaveDrain); 229 } 230 } 231 232 void MarkStackThreadSharedData::markingThreadStartFunc(void* shared) 233 { 234 static_cast<MarkStackThreadSharedData*>(shared)->markingThreadMain(); 241 ParallelModeEnabler enabler(*slotVisitor); 242 slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); 243 } 244 delete slotVisitor; 245 } 246 247 void MarkStackThreadSharedData::markingThreadStartFunc(void* myVisitor) 248 { 249 SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor); 250 251 slotVisitor->sharedData().markingThreadMain(slotVisitor); 235 252 } 236 253 #endif … … 245 262 #if ENABLE(PARALLEL_GC) 246 263 for (unsigned i = 1; i < Options::numberOfGCMarkers; ++i) { 247 m_markingThreads.append(createThread(markingThreadStartFunc, this, "JavaScriptCore::Marking")); 264 SlotVisitor* slotVisitor = new SlotVisitor(*this); 265 m_markingThreadsMarkStack.append(slotVisitor); 266 m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking")); 248 267 ASSERT(m_markingThreads.last()); 249 268 } … … 277 296 ASSERT(m_opaqueRoots.isEmpty()); 278 297 #endif 279 280 298 m_weakReferenceHarvesters.removeAll(); 281 299 } -
trunk/Source/JavaScriptCore/heap/MarkStack.h
r116822 r119633 35 35 #include "VTableSpectrum.h" 36 36 #include "WeakReferenceHarvester.h" 37 #include <wtf/DataLog.h> 38 #include <wtf/Forward.h> 37 39 #include <wtf/HashMap.h> 38 40 #include <wtf/HashSet.h> … … 41 43 #include <wtf/OSAllocator.h> 42 44 #include <wtf/PageBlock.h> 45 #include <wtf/text/StringHash.h> 46 47 #if ENABLE(OBJECT_MARK_LOGGING) 48 #define MARK_LOG_MESSAGE0(message) dataLog(message) 49 #define MARK_LOG_MESSAGE1(message, arg1) dataLog(message, arg1) 50 #define MARK_LOG_MESSAGE2(message, arg1, arg2) dataLog(message, arg1, arg2) 51 #define MARK_LOG_ROOT(visitor, rootName) \ 52 dataLog("\n%s: ", rootName); \ 53 (visitor).resetChildCount() 54 #define MARK_LOG_PARENT(visitor, parent) \ 55 dataLog("\n%p (%s): ", parent, parent->className() ? parent->className() : "unknown"); \ 56 (visitor).resetChildCount() 57 #define MARK_LOG_CHILD(visitor, child) \ 58 if ((visitor).childCount()) \ 59 dataLogString(", "); \ 60 dataLog("%p", child); \ 61 (visitor).incrementChildCount() 62 #else 63 #define MARK_LOG_MESSAGE0(message) do { } while (false) 64 #define MARK_LOG_MESSAGE1(message, arg1) do { } while (false) 65 #define MARK_LOG_MESSAGE2(message, arg1, arg2) do { } while (false) 66 #define MARK_LOG_ROOT(visitor, rootName) do { } while (false) 67 #define MARK_LOG_PARENT(visitor, parent) do { } while (false) 68 #define MARK_LOG_CHILD(visitor, child) do { } while (false) 69 #endif 43 70 44 71 namespace JSC { … … 172 199 173 200 void reset(); 201 202 #if ENABLE(PARALLEL_GC) 203 void resetChildren(); 204 size_t childVisitCount(); 205 size_t childDupStrings(); 206 #endif 174 207 175 208 private: … … 178 211 179 212 #if ENABLE(PARALLEL_GC) 180 void markingThreadMain( );213 void markingThreadMain(SlotVisitor*); 181 214 static void markingThreadStartFunc(void* heap); 182 215 #endif … … 188 221 189 222 Vector<ThreadIdentifier> m_markingThreads; 223 Vector<MarkStack*> m_markingThreadsMarkStack; 190 224 191 225 Mutex m_markingLock; … … 222 256 bool containsOpaqueRoot(void*); 223 257 int opaqueRootCount(); 224 258 259 MarkStackThreadSharedData& sharedData() { return m_shared; } 225 260 bool isEmpty() { return m_stack.isEmpty(); } 226 261 … … 242 277 m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer); 243 278 } 279 280 #if ENABLE(OBJECT_MARK_LOGGING) 281 inline void resetChildCount() { m_logChildCount = 0; } 282 inline unsigned childCount() { return m_logChildCount; } 283 inline void incrementChildCount() { m_logChildCount++; } 284 #endif 244 285 245 286 protected: … … 284 325 285 326 MarkStackThreadSharedData& m_shared; 327 328 #if ENABLE(OBJECT_MARK_LOGGING) 329 unsigned m_logChildCount; 330 #endif 286 331 }; 287 332 -
trunk/Source/JavaScriptCore/runtime/JSArray.cpp
r116828 r119633 1372 1372 1373 1373 if (thisObject->m_storage) { 1374 MARK_LOG_MESSAGE1("[%u]: ", thisObject->length()); 1375 1374 1376 ArrayStorage* storage = thisObject->m_storage; 1375 1377 void* baseStorage = storage->m_allocBase; -
trunk/Source/JavaScriptCore/runtime/JSCell.cpp
r116828 r119633 185 185 } 186 186 187 const char* JSCell::className() 188 { 189 return classInfo()->className; 190 } 191 187 192 void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) 188 193 { -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r117646 r119633 85 85 void clearStructure() { m_structure.clear(); } 86 86 87 const char* className(); 88 87 89 // Extracting the value. 88 90 JS_EXPORT_PRIVATE bool getString(ExecState* exec, UString&) const; … … 198 200 inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor) 199 201 { 202 MARK_LOG_PARENT(visitor, cell); 203 200 204 visitor.append(&cell->m_structure); 201 205 } -
trunk/Source/JavaScriptCore/runtime/JSString.cpp
r118616 r119633 57 57 Base::visitChildren(thisObject, visitor); 58 58 59 MARK_LOG_MESSAGE1("[%u]: ", thisObject->length()); 60 61 #if ENABLE(OBJECT_MARK_LOGGING) 62 if (!thisObject->isRope()) { 63 WTF::StringImpl* ourImpl = thisObject->m_value.impl(); 64 if (ourImpl->is8Bit()) 65 MARK_LOG_MESSAGE1("[8 %p]", ourImpl->characters8()); 66 else 67 MARK_LOG_MESSAGE1("[16 %p]", ourImpl->characters16()); 68 } else 69 MARK_LOG_MESSAGE0("[rope]: "); 70 #endif 71 59 72 if (thisObject->isRope()) 60 73 static_cast<JSRopeString*>(thisObject)->visitFibers(visitor); -
trunk/Source/JavaScriptCore/runtime/JSString.h
r119016 r119633 68 68 friend class SpecializedThunkJIT; 69 69 friend class JSRopeString; 70 friend class SlotVisitor; 70 71 friend struct ThunkHelpers; 71 72 -
trunk/Source/JavaScriptCore/runtime/Structure.h
r118555 r119633 383 383 validate(cell); 384 384 #endif 385 m_visitCount++;386 385 if (Heap::testAndSetMarked(cell) || !cell->structure()) 387 386 return; 388 387 388 m_visitCount++; 389 390 MARK_LOG_CHILD(*this, cell); 391 389 392 // Should never attempt to mark something that is zapped. 390 393 ASSERT(!cell->isZapped()); -
trunk/Source/WTF/ChangeLog
r119593 r119633 1 2012-06-06 Michael Saboff <msaboff@apple.com> 2 3 ENH: Add Logging to GC Marking Phase 4 https://bugs.webkit.org/show_bug.cgi?id=88364 5 6 Reviewed by Filip Pizlo. 7 8 * wtf/DataLog.cpp: 9 (WTF::dataLogString): Additional method to support GC Mark logging. 10 * wtf/DataLog.h: 11 * wtf/Platform.h: New ENABLE_OBJECT_MARK_LOGGING flag macro. 12 1 13 2012-06-06 Andy Wingo <wingo@igalia.com> 2 14 -
trunk/Source/WTF/wtf/DataLog.cpp
r111778 r119633 96 96 } 97 97 98 void dataLogString(const char* str) 99 { 100 fputs(str, dataFile()); 101 } 102 98 103 } // namespace WTF 99 104 -
trunk/Source/WTF/wtf/DataLog.h
r119157 r119633 38 38 WTF_EXPORT_PRIVATE void dataLogV(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(1, 0); 39 39 WTF_EXPORT_PRIVATE void dataLog(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2); 40 WTF_EXPORT_PRIVATE void dataLogString(const char*); 40 41 41 42 } // namespace WTF 42 43 43 44 using WTF::dataLog; 45 using WTF::dataLogString; 44 46 45 47 #endif // DataLog_h -
trunk/Source/WTF/wtf/Platform.h
r119593 r119633 1073 1073 #endif 1074 1074 1075 #if !defined(ENABLE_PARALLEL_GC) && (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(QT) || PLATFORM(BLACKBERRY)) && ENABLE(COMPARE_AND_SWAP) 1075 #define ENABLE_OBJECT_MARK_LOGGING 0 1076 1077 #if !defined(ENABLE_PARALLEL_GC) && !ENABLE(OBJECT_MARK_LOGGING) && (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(QT) || PLATFORM(BLACKBERRY)) && ENABLE(COMPARE_AND_SWAP) 1076 1078 #define ENABLE_PARALLEL_GC 1 1077 1079 #endif
Note: See TracChangeset
for help on using the changeset viewer.