Title: [220322] trunk
Revision
220322
Author
fpi...@apple.com
Date
2017-08-05 21:43:37 -0700 (Sat, 05 Aug 2017)

Log Message

REGRESSION (r219895-219897): Number of leaks on Open Source went from 9240 to 235983 and is now at 302372
https://bugs.webkit.org/show_bug.cgi?id=175083

Reviewed by Oliver Hunt.
        
Source/_javascript_Core:

This fixes the leak by making MarkedBlock::specializedSweep call destructors when the block is empty,
even if we are using the pop path.
        
Also, this fixes HeapCellInlines.h to no longer include MarkedBlockInlines.h. That's pretty
important, since MarkedBlockInlines.h is the GC's internal guts - we don't want to have to recompile
the world just because we changed it.
        
Finally, this adds a new testing SPI for waiting for all VMs to finish destructing. This makes it
easier to debug leaks.

* bytecode/AccessCase.cpp:
* bytecode/PolymorphicAccess.cpp:
* heap/HeapCell.cpp:
(JSC::HeapCell::isLive):
* heap/HeapCellInlines.h:
(JSC::HeapCell::isLive): Deleted.
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::tryAllocateWithoutCollecting):
(JSC::MarkedAllocator::endMarking):
* heap/MarkedBlockInlines.h:
(JSC::MarkedBlock::Handle::specializedSweep):
* jit/AssemblyHelpers.cpp:
* jit/Repatch.cpp:
* runtime/TestRunnerUtils.h:
* runtime/VM.cpp:
(JSC::waitForVMDestruction):
(JSC::VM::~VM):

Source/WTF:

Adds a classic ReadWriteLock class. I wrote my own because I can never remember if the pthread one is
guaranted to bias in favor of writers or not.

* WTF.xcodeproj/project.pbxproj:
* wtf/Condition.h:
(WTF::ConditionBase::construct):
(WTF::Condition::Condition):
* wtf/Lock.h:
(WTF::LockBase::construct):
(WTF::Lock::Lock):
* wtf/ReadWriteLock.cpp: Added.
(WTF::ReadWriteLockBase::construct):
(WTF::ReadWriteLockBase::readLock):
(WTF::ReadWriteLockBase::readUnlock):
(WTF::ReadWriteLockBase::writeLock):
(WTF::ReadWriteLockBase::writeUnlock):
* wtf/ReadWriteLock.h: Added.
(WTF::ReadWriteLockBase::ReadLock::tryLock):
(WTF::ReadWriteLockBase::ReadLock::lock):
(WTF::ReadWriteLockBase::ReadLock::unlock):
(WTF::ReadWriteLockBase::WriteLock::tryLock):
(WTF::ReadWriteLockBase::WriteLock::lock):
(WTF::ReadWriteLockBase::WriteLock::unlock):
(WTF::ReadWriteLockBase::read):
(WTF::ReadWriteLockBase::write):
(WTF::ReadWriteLock::ReadWriteLock):

Tools:

Leaks results are super confusing if leaks runs while some VMs are destructing. This calls a new SPI
to wait for VM destructions to finish before running the next test. This makes it easier to 
understand leaks results from workers tests, and leads to fewer reported leaks.

* DumpRenderTree/mac/DumpRenderTree.mm:
(runTest):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (220321 => 220322)


--- trunk/Source/_javascript_Core/ChangeLog	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-08-06 04:43:37 UTC (rev 220322)
@@ -1,3 +1,38 @@
+2017-08-05  Filip Pizlo  <fpi...@apple.com>
+
+        REGRESSION (r219895-219897): Number of leaks on Open Source went from 9240 to 235983 and is now at 302372
+        https://bugs.webkit.org/show_bug.cgi?id=175083
+
+        Reviewed by Oliver Hunt.
+        
+        This fixes the leak by making MarkedBlock::specializedSweep call destructors when the block is empty,
+        even if we are using the pop path.
+        
+        Also, this fixes HeapCellInlines.h to no longer include MarkedBlockInlines.h. That's pretty
+        important, since MarkedBlockInlines.h is the GC's internal guts - we don't want to have to recompile
+        the world just because we changed it.
+        
+        Finally, this adds a new testing SPI for waiting for all VMs to finish destructing. This makes it
+        easier to debug leaks.
+
+        * bytecode/AccessCase.cpp:
+        * bytecode/PolymorphicAccess.cpp:
+        * heap/HeapCell.cpp:
+        (JSC::HeapCell::isLive):
+        * heap/HeapCellInlines.h:
+        (JSC::HeapCell::isLive): Deleted.
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::tryAllocateWithoutCollecting):
+        (JSC::MarkedAllocator::endMarking):
+        * heap/MarkedBlockInlines.h:
+        (JSC::MarkedBlock::Handle::specializedSweep):
+        * jit/AssemblyHelpers.cpp:
+        * jit/Repatch.cpp:
+        * runtime/TestRunnerUtils.h:
+        * runtime/VM.cpp:
+        (JSC::waitForVMDestruction):
+        (JSC::VM::~VM):
+
 2017-08-05  Mark Lam  <mark....@apple.com>
 
         Move DFG::OSRExitCompiler methods into DFG::OSRExit [step 3].

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -46,6 +46,7 @@
 #include "ScratchRegisterAllocator.h"
 #include "SlotVisitorInlines.h"
 #include "StructureStubInfo.h"
+#include "SuperSampler.h"
 #include "ThunkGenerators.h"
 
 namespace JSC {

Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -38,6 +38,7 @@
 #include "LinkBuffer.h"
 #include "StructureStubClearingWatchpoint.h"
 #include "StructureStubInfo.h"
+#include "SuperSampler.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/ListDump.h>
 

Modified: trunk/Source/_javascript_Core/heap/HeapCell.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/heap/HeapCell.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/heap/HeapCell.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -26,10 +26,22 @@
 #include "config.h"
 #include "HeapCell.h"
 
+#include "HeapCellInlines.h"
+#include "MarkedBlockInlines.h"
 #include <wtf/PrintStream.h>
 
 namespace JSC {
 
+bool HeapCell::isLive()
+{
+    if (isLargeAllocation())
+        return largeAllocation().isLive();
+    auto& markedBlockHandle = markedBlock().handle();
+    if (markedBlockHandle.isFreeListed())
+        return !markedBlockHandle.isFreeListedCell(this);
+    return markedBlockHandle.isLive(this);
+}
+
 #if !COMPILER(GCC_OR_CLANG)
 void HeapCell::use() const
 {

Modified: trunk/Source/_javascript_Core/heap/HeapCellInlines.h (220321 => 220322)


--- trunk/Source/_javascript_Core/heap/HeapCellInlines.h	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/heap/HeapCellInlines.h	2017-08-06 04:43:37 UTC (rev 220322)
@@ -28,21 +28,10 @@
 #include "CellContainer.h"
 #include "HeapCell.h"
 #include "LargeAllocation.h"
-#include "MarkedBlockInlines.h"
 #include "VM.h"
 
 namespace JSC {
 
-ALWAYS_INLINE bool HeapCell::isLive()
-{
-    if (isLargeAllocation())
-        return largeAllocation().isLive();
-    auto& markedBlockHandle = markedBlock().handle();
-    if (markedBlockHandle.isFreeListed())
-        return !markedBlockHandle.isFreeListedCell(this);
-    return markedBlockHandle.isLive(this);
-}
-
 ALWAYS_INLINE bool HeapCell::isLargeAllocation() const
 {
     return LargeAllocation::isLargeAllocation(const_cast<HeapCell*>(this));

Modified: trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -39,6 +39,8 @@
 
 namespace JSC {
 
+static constexpr bool tradeDestructorBlocks = true;
+
 MarkedAllocator::MarkedAllocator(Heap* heap, Subspace* subspace, size_t cellSize)
     : m_freeList(cellSize)
     , m_currentBlock(0)
@@ -102,7 +104,8 @@
             return result;
     }
     
-    if (Options::stealEmptyBlocksFromOtherAllocators()) {
+    if (Options::stealEmptyBlocksFromOtherAllocators()
+        && (tradeDestructorBlocks || !needsDestruction())) {
         if (MarkedBlock::Handle* block = m_subspace->findEmptyBlockToSteal()) {
             RELEASE_ASSERT(block->alignedMemoryAllocator() == m_subspace->alignedMemoryAllocator());
             
@@ -381,8 +384,14 @@
     // know what kind of collection it is. That knowledge is already encoded in the m_markingXYZ
     // vectors.
     
-    m_empty = m_live & ~m_markingNotEmpty;
-    m_canAllocateButNotEmpty = m_live & m_markingNotEmpty & ~m_markingRetired;
+    if (!tradeDestructorBlocks && needsDestruction()) {
+        ASSERT(m_empty.isEmpty());
+        m_canAllocateButNotEmpty = m_live & ~m_markingRetired;
+    } else {
+        m_empty = m_live & ~m_markingNotEmpty;
+        m_canAllocateButNotEmpty = m_live & m_markingNotEmpty & ~m_markingRetired;
+    }
+    
     if (needsDestruction()) {
         // There are some blocks that we didn't allocate out of in the last cycle, but we swept them. This
         // will forget that we did that and we will end up sweeping them again and attempting to call their

Modified: trunk/Source/_javascript_Core/heap/MarkedBlockInlines.h (220321 => 220322)


--- trunk/Source/_javascript_Core/heap/MarkedBlockInlines.h	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/heap/MarkedBlockInlines.h	2017-08-06 04:43:37 UTC (rev 220322)
@@ -223,7 +223,7 @@
     auto handleDeadCell = [&] (size_t i) {
         HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&block.atoms()[i]);
 
-        if (destructionMode != BlockHasNoDestructors && emptyMode == NotEmpty)
+        if (destructionMode != BlockHasNoDestructors)
             destroy(cell);
 
         if (sweepMode == SweepToFreeList) {

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -32,6 +32,7 @@
 #include "JSCInlines.h"
 #include "LinkBuffer.h"
 #include "MaxFrameExtentForSlowPathCall.h"
+#include "SuperSampler.h"
 #include "ThunkGenerators.h"
 
 #if ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -58,6 +58,7 @@
 #include "StructureRareDataInlines.h"
 #include "StructureStubClearingWatchpoint.h"
 #include "StructureStubInfo.h"
+#include "SuperSampler.h"
 #include "ThunkGenerators.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/ListDump.h>

Modified: trunk/Source/_javascript_Core/runtime/TestRunnerUtils.h (220321 => 220322)


--- trunk/Source/_javascript_Core/runtime/TestRunnerUtils.h	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/runtime/TestRunnerUtils.h	2017-08-06 04:43:37 UTC (rev 220322)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,4 +54,6 @@
 
 JS_EXPORT_PRIVATE void finalizeStatsAtEndOfTesting();
 
+JS_EXPORT_PRIVATE void waitForVMDestruction();
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (220321 => 220322)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -101,6 +101,7 @@
 #include "StrictEvalActivation.h"
 #include "StrongInlines.h"
 #include "StructureInlines.h"
+#include "TestRunnerUtils.h"
 #include "ThunkGenerators.h"
 #include "TypeProfiler.h"
 #include "TypeProfilerLog.h"
@@ -113,6 +114,7 @@
 #include "WeakMapData.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/ProcessID.h>
+#include <wtf/ReadWriteLock.h>
 #include <wtf/SimpleStats.h>
 #include <wtf/StringPrintStream.h>
 #include <wtf/Threading.h>
@@ -341,8 +343,17 @@
     VMInspector::instance().add(this);
 }
 
+static StaticReadWriteLock s_destructionLock;
+
+void waitForVMDestruction()
+{
+    auto locker = holdLock(s_destructionLock.write());
+}
+
 VM::~VM()
 {
+    auto destructionLocker = holdLock(s_destructionLock.read());
+    
     Gigacage::removeDisableCallback(gigacageDisabledCallback, this);
     promiseDeferredTimer->stopRunningTasks();
 #if ENABLE(WEBASSEMBLY)

Modified: trunk/Source/WTF/ChangeLog (220321 => 220322)


--- trunk/Source/WTF/ChangeLog	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/WTF/ChangeLog	2017-08-06 04:43:37 UTC (rev 220322)
@@ -1,3 +1,37 @@
+2017-08-05  Filip Pizlo  <fpi...@apple.com>
+
+        REGRESSION (r219895-219897): Number of leaks on Open Source went from 9240 to 235983 and is now at 302372
+        https://bugs.webkit.org/show_bug.cgi?id=175083
+
+        Reviewed by Oliver Hunt.
+        
+        Adds a classic ReadWriteLock class. I wrote my own because I can never remember if the pthread one is
+        guaranted to bias in favor of writers or not.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/Condition.h:
+        (WTF::ConditionBase::construct):
+        (WTF::Condition::Condition):
+        * wtf/Lock.h:
+        (WTF::LockBase::construct):
+        (WTF::Lock::Lock):
+        * wtf/ReadWriteLock.cpp: Added.
+        (WTF::ReadWriteLockBase::construct):
+        (WTF::ReadWriteLockBase::readLock):
+        (WTF::ReadWriteLockBase::readUnlock):
+        (WTF::ReadWriteLockBase::writeLock):
+        (WTF::ReadWriteLockBase::writeUnlock):
+        * wtf/ReadWriteLock.h: Added.
+        (WTF::ReadWriteLockBase::ReadLock::tryLock):
+        (WTF::ReadWriteLockBase::ReadLock::lock):
+        (WTF::ReadWriteLockBase::ReadLock::unlock):
+        (WTF::ReadWriteLockBase::WriteLock::tryLock):
+        (WTF::ReadWriteLockBase::WriteLock::lock):
+        (WTF::ReadWriteLockBase::WriteLock::unlock):
+        (WTF::ReadWriteLockBase::read):
+        (WTF::ReadWriteLockBase::write):
+        (WTF::ReadWriteLock::ReadWriteLock):
+
 2017-08-04  Matt Lewis  <jlew...@apple.com>
 
         Unreviewed, rolling out r220271.

Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (220321 => 220322)


--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2017-08-06 04:43:37 UTC (rev 220322)
@@ -38,6 +38,7 @@
 		0FDDBFA71666DFA300C55FEF /* StringPrintStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFA51666DFA300C55FEF /* StringPrintStream.cpp */; };
 		0FE1646A1B6FFC9600400E7C /* Lock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE164681B6FFC9600400E7C /* Lock.cpp */; };
 		0FE4479C1B7AAA03009498EB /* WordLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE4479A1B7AAA03009498EB /* WordLock.cpp */; };
+		0FEC3C5E1F368A9700F59B6C /* ReadWriteLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC3C5C1F368A9700F59B6C /* ReadWriteLock.cpp */; };
 		0FFF19DC1BB334EB00886D91 /* ParallelHelperPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFF19DA1BB334EB00886D91 /* ParallelHelperPool.cpp */; };
 		14022F4118F5C3FC007FF0EB /* libbmalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14022F4018F5C3FC007FF0EB /* libbmalloc.a */; };
 		143F611F1565F0F900DB514A /* RAMSize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 143F611D1565F0F900DB514A /* RAMSize.cpp */; };
@@ -225,6 +226,8 @@
 		0FEB3DCE1BB5D684009D7AAD /* SharedTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTask.h; sourceTree = "<group>"; };
 		0FEB3DD01BB7366B009D7AAD /* ParallelVectorIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParallelVectorIterator.h; sourceTree = "<group>"; };
 		0FEC3C4F1F323C6800F59B6C /* CagedPtr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CagedPtr.h; sourceTree = "<group>"; };
+		0FEC3C5C1F368A9700F59B6C /* ReadWriteLock.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ReadWriteLock.cpp; sourceTree = "<group>"; };
+		0FEC3C5D1F368A9700F59B6C /* ReadWriteLock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReadWriteLock.h; sourceTree = "<group>"; };
 		0FEC84AE1BD825310080FF74 /* GraphNodeWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphNodeWorklist.h; sourceTree = "<group>"; };
 		0FEC84B01BDACD390080FF74 /* ScopedLambda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedLambda.h; sourceTree = "<group>"; };
 		0FED67B51B22D4D80066CE15 /* TinyPtrSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TinyPtrSet.h; sourceTree = "<group>"; };
@@ -909,6 +912,8 @@
 				0F2AC5601E89F70C0001EE3F /* Range.h */,
 				0F725CAB1C50461600AD943A /* RangeSet.h */,
 				0F87105916643F190090B0AD /* RawPointer.h */,
+				0FEC3C5C1F368A9700F59B6C /* ReadWriteLock.cpp */,
+				0FEC3C5D1F368A9700F59B6C /* ReadWriteLock.h */,
 				0FDE87F61DFD07CC0064C390 /* RecursiveLockAdapter.h */,
 				A8A472FE151A825B004123FF /* RedBlackTree.h */,
 				26299B6D17A9E5B800ADEBE5 /* Ref.h */,
@@ -1337,6 +1342,7 @@
 				A8A473D8151A825B004123FF /* HashTable.cpp in Sources */,
 				0FE1646A1B6FFC9600400E7C /* Lock.cpp in Sources */,
 				0F60F32F1DFCBD1B00416D6C /* LockedPrintStream.cpp in Sources */,
+				0FEC3C5E1F368A9700F59B6C /* ReadWriteLock.cpp in Sources */,
 				53534F2A1EC0E10E00141B2F /* MachExceptions.defs in Sources */,
 				A8A473E5151A825B004123FF /* MainThread.cpp in Sources */,
 				A8A473E4151A825B004123FF /* MainThreadMac.mm in Sources */,

Modified: trunk/Source/WTF/wtf/CMakeLists.txt (220321 => 220322)


--- trunk/Source/WTF/wtf/CMakeLists.txt	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/WTF/wtf/CMakeLists.txt	2017-08-06 04:43:37 UTC (rev 220322)
@@ -110,6 +110,7 @@
     Range.h
     RangeSet.h
     RawPointer.h
+    ReadWriteLock.h
     RecursiveLockAdapter.h
     RedBlackTree.h
     Ref.h
@@ -241,6 +242,7 @@
     RAMSize.cpp
     RandomDevice.cpp
     RandomNumber.cpp
+    ReadWriteLock.cpp
     RefCountedLeakCounter.cpp
     RunLoop.cpp
     SHA1.cpp

Modified: trunk/Source/WTF/wtf/Condition.h (220321 => 220322)


--- trunk/Source/WTF/wtf/Condition.h	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/WTF/wtf/Condition.h	2017-08-06 04:43:37 UTC (rev 220322)
@@ -50,6 +50,11 @@
     // are unlikely to be affected by the cost of conversions, it is better to use MonotonicTime.
     typedef ParkingLot::Time Time;
     
+    void construct()
+    {
+        m_hasWaiters.store(false);
+    }
+    
     // Wait on a parking queue while releasing the given lock. It will unlock the lock just before
     // parking, and relock it upon wakeup. Returns true if we woke up due to some call to
     // notifyOne() or notifyAll(). Returns false if we woke up due to a timeout. Note that this form
@@ -168,7 +173,7 @@
         ParkingLot::unparkAll(&m_hasWaiters);
     }
     
-protected:
+private:
     Atomic<bool> m_hasWaiters;
 };
 
@@ -177,7 +182,7 @@
 public:
     Condition()
     {
-        m_hasWaiters.store(false);
+        construct();
     }
 };
 

Modified: trunk/Source/WTF/wtf/Lock.h (220321 => 220322)


--- trunk/Source/WTF/wtf/Lock.h	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Source/WTF/wtf/Lock.h	2017-08-06 04:43:37 UTC (rev 220322)
@@ -52,6 +52,11 @@
 // This is a struct without a constructor or destructor so that it can be statically initialized.
 // Use Lock in instance variables.
 struct LockBase {
+    void construct()
+    {
+        m_byte.store(0, std::memory_order_relaxed);
+    }
+    
     void lock()
     {
         if (UNLIKELY(!DefaultLockAlgorithm::lockFastAssumingZero(m_byte)))
@@ -110,7 +115,7 @@
         return isHeld();
     }
 
-protected:
+private:
     friend struct TestWebKitAPI::LockInspector;
     
     static const uint8_t isHeldBit = 1;
@@ -136,7 +141,7 @@
 public:
     Lock()
     {
-        m_byte.store(0, std::memory_order_relaxed);
+        construct();
     }
 };
 

Added: trunk/Source/WTF/wtf/ReadWriteLock.cpp (0 => 220322)


--- trunk/Source/WTF/wtf/ReadWriteLock.cpp	                        (rev 0)
+++ trunk/Source/WTF/wtf/ReadWriteLock.cpp	2017-08-06 04:43:37 UTC (rev 220322)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ReadWriteLock.h"
+
+#include <wtf/Locker.h>
+
+namespace WTF {
+
+void ReadWriteLockBase::construct()
+{
+    m_lock.construct();
+    m_cond.construct();
+    m_isWriteLocked = false;
+    m_numReaders = 0;
+    m_numWaitingWriters = 0;
+}
+
+void ReadWriteLockBase::readLock()
+{
+    auto locker = holdLock(m_lock);
+    while (m_isWriteLocked || m_numWaitingWriters)
+        m_cond.wait(m_lock);
+    m_numReaders++;
+}
+
+void ReadWriteLockBase::readUnlock()
+{
+    auto locker = holdLock(m_lock);
+    m_numReaders--;
+    if (!m_numReaders)
+        m_cond.notifyAll();
+}
+
+void ReadWriteLockBase::writeLock()
+{
+    auto locker = holdLock(m_lock);
+    while (m_isWriteLocked || m_numReaders) {
+        m_numWaitingWriters++;
+        m_cond.wait(m_lock);
+        m_numWaitingWriters--;
+    }
+    m_isWriteLocked = true;
+}
+
+void ReadWriteLockBase::writeUnlock()
+{
+    auto locker = holdLock(m_lock);
+    m_isWriteLocked = false;
+    m_cond.notifyAll();
+}
+
+} // namespace WTF
+

Added: trunk/Source/WTF/wtf/ReadWriteLock.h (0 => 220322)


--- trunk/Source/WTF/wtf/ReadWriteLock.h	                        (rev 0)
+++ trunk/Source/WTF/wtf/ReadWriteLock.h	2017-08-06 04:43:37 UTC (rev 220322)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+#include <wtf/Condition.h>
+#include <wtf/Lock.h>
+
+namespace WTF {
+
+// This is a traditional read-write lock implementation that enables concurrency between readers so long as
+// the read critical section is long. Concurrent readers will experience contention on read().lock() and
+// read().unlock() if the work inside the critical section is short. The more cores participate in reading,
+// the longer the read critical section has to be for this locking scheme to be profitable.
+
+struct ReadWriteLockBase {
+    WTF_EXPORT_PRIVATE void construct();
+    
+    // It's easiest to read lock like this:
+    // 
+    //     auto locker = holdLock(rwLock.read());
+    //
+    // It's easiest to write lock like this:
+    // 
+    //     auto locker = holdLock(rwLock.write());
+    //
+    WTF_EXPORT_PRIVATE void readLock();
+    WTF_EXPORT_PRIVATE void readUnlock();
+    WTF_EXPORT_PRIVATE void writeLock();
+    WTF_EXPORT_PRIVATE void writeUnlock();
+    
+    class ReadLock;
+    class WriteLock;
+
+    ReadLock& read();
+    WriteLock& write();
+
+private:
+    // These fields must work when zero-filled, so that StaticReadWriteLock works.
+    LockBase m_lock;
+    ConditionBase m_cond;
+    bool m_isWriteLocked;
+    unsigned m_numReaders;
+    unsigned m_numWaitingWriters;
+};
+
+class ReadWriteLockBase::ReadLock : public ReadWriteLockBase {
+public:
+    bool tryLock() { return false; }
+    void lock() { readLock(); }
+    void unlock() { readUnlock(); }
+};
+
+class ReadWriteLockBase::WriteLock : public ReadWriteLockBase {
+public:
+    bool tryLock() { return false; }
+    void lock() { writeLock(); }
+    void unlock() { writeUnlock(); }
+};
+    
+inline ReadWriteLockBase::ReadLock& ReadWriteLockBase::read() { return *static_cast<ReadLock*>(this); }
+inline ReadWriteLockBase::WriteLock& ReadWriteLockBase::write() { return *static_cast<WriteLock*>(this); }
+
+class ReadWriteLock : public ReadWriteLockBase {
+public:
+    ReadWriteLock()
+    {
+        construct();
+    }
+};
+
+typedef ReadWriteLockBase StaticReadWriteLock;
+
+} // namespace WTF
+
+using WTF::ReadWriteLock;
+using WTF::StaticReadWriteLock;
+

Modified: trunk/Tools/ChangeLog (220321 => 220322)


--- trunk/Tools/ChangeLog	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Tools/ChangeLog	2017-08-06 04:43:37 UTC (rev 220322)
@@ -1,3 +1,17 @@
+2017-08-05  Filip Pizlo  <fpi...@apple.com>
+
+        REGRESSION (r219895-219897): Number of leaks on Open Source went from 9240 to 235983 and is now at 302372
+        https://bugs.webkit.org/show_bug.cgi?id=175083
+
+        Reviewed by Oliver Hunt.
+        
+        Leaks results are super confusing if leaks runs while some VMs are destructing. This calls a new SPI
+        to wait for VM destructions to finish before running the next test. This makes it easier to 
+        understand leaks results from workers tests, and leads to fewer reported leaks.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (runTest):
+
 2017-08-05  Yoshiaki Jitsukawa  <yoshiaki.jitsuk...@sony.com>
 
         check-webkit-style: fix path-specific rules for WebKit2 rename

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (220321 => 220322)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2017-08-05 23:48:26 UTC (rev 220321)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2017-08-06 04:43:37 UTC (rev 220322)
@@ -2088,6 +2088,8 @@
 
     if (gcBetweenTests)
         [WebCoreStatistics garbageCollectJavaScriptObjects];
+    
+    JSC::waitForVMDestruction();
 
     fputs("#EOF\n", stderr);
     fflush(stderr);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to