haikuwebkit/Source/WTF/wtf/TimeWithDynamicClockType.cpp

146 lines
4.2 KiB
C++
Raw Permalink Normal View History

WTF::ParkingLot should stop using std::chrono because std::chrono::duration casts are prone to overflows https://bugs.webkit.org/show_bug.cgi?id=152045 Reviewed by Andy Estes. Source/JavaScriptCore: Probably the nicest example of why this patch is a good idea is the change in AtomicsObject.cpp. * jit/ICStats.cpp: (JSC::ICStats::ICStats): * runtime/AtomicsObject.cpp: (JSC::atomicsFuncWait): Source/WebCore: No new layout tests because no new behavior. The new WTF time classes have some unit tests in TestWebKitAPI. * fileapi/ThreadableBlobRegistry.cpp: (WebCore::ThreadableBlobRegistry::blobSize): * platform/MainThreadSharedTimer.h: * platform/SharedTimer.h: * platform/ThreadTimers.cpp: (WebCore::ThreadTimers::updateSharedTimer): * platform/cf/MainThreadSharedTimerCF.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/efl/MainThreadSharedTimerEfl.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/glib/MainThreadSharedTimerGLib.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/win/MainThreadSharedTimerWin.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * workers/WorkerRunLoop.cpp: (WebCore::WorkerRunLoop::runInMode): Source/WebKit2: * Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageState::wait): (IPC::Connection::sendMessage): (IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting): (IPC::Connection::waitForMessage): (IPC::Connection::sendSyncMessage): (IPC::Connection::waitForSyncReply): * Platform/IPC/Connection.h: (IPC::Connection::sendSync): (IPC::Connection::waitForAndDispatchImmediately): * Platform/IPC/MessageSender.h: (IPC::MessageSender::sendSync): * UIProcess/ChildProcessProxy.h: (WebKit::ChildProcessProxy::sendSync): * UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): * UIProcess/Storage/StorageManager.cpp: (WebKit::StorageManager::applicationWillTerminate): * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::sendProcessWillSuspendImminently): * UIProcess/WebResourceLoadStatisticsStore.cpp: (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate): * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (-[WKOneShotDisplayLinkHandler displayLinkFired:]): (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay): (WebKit::RemoteLayerTreeDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/WKImmediateActionController.mm: (-[WKImmediateActionController immediateActionRecognizerWillBeginAnimation:]): * UIProcess/mac/WebPageProxyMac.mm: (WebKit::WebPageProxy::stringSelectionForPasteboard): (WebKit::WebPageProxy::dataSelectionForPasteboard): (WebKit::WebPageProxy::readSelectionFromPasteboard): (WebKit::WebPageProxy::shouldDelayWindowOrderingForEvent): (WebKit::WebPageProxy::acceptsFirstMouse): * WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): (WebKit::WebChromeClient::runJavaScriptAlert): (WebKit::WebChromeClient::runJavaScriptConfirm): (WebKit::WebChromeClient::runJavaScriptPrompt): (WebKit::WebChromeClient::print): (WebKit::WebChromeClient::exceededDatabaseQuota): (WebKit::WebChromeClient::reachedApplicationCacheOriginQuota): * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::postSynchronousMessageForTesting): Source/WTF: We used to use 'double' for all time measurements. Sometimes it was milliseconds, sometimes it was seconds. Sometimes we measured a span of time, sometimes we spoke of time since some epoch. When we spoke of time since epoch, we either used a monotonic clock or a wall clock. The type - always 'double' - never told us what kind of time we had, even though there were roughly six of them (sec interval, ms interval, sec since epoch on wall, ms since epoch on wall, sec since epoch monotonic, ms since epoch monotonic). At some point, we thought that it would be a good idea to replace these doubles with std::chrono. But since replacing some things with std::chrono, we found it to be terribly inconvenient: - Outrageous API. I never want to say std::chrono::milliseconds(blah). I never want to say std::chrono::steady_clock::timepoint. The syntax for duration_cast is ugly, and ideally duration_cast would not even be a thing. - No overflow protection. std::chrono uses integers by default and using anything else is clumsy. But the integer math is done without regard for the rough edges of integer math, so any cast between std::chrono types risks overflow. Any comparison risks overflow because it may do conversions silently. We have even found bugs where some C++ implementations had more overflows than others, which ends up being a special kind of hell. In many cases, the overflow also has nasal demons. It's an error to represent time using integers. It would have been excusable back when floating point math was not guaranteed to be supported on all platforms, but that would have been a long time ago. Time is a continuous, infinite concept and it's a perfect fit for floating point: - Floating point preserves precision under multiplication in all but extreme cases, so using floating point for time means that unit conversions are almost completely lossless. This means that we don't have to think very hard about what units to use. In this patch, we use seconds almost everywhere. We only convert at boundaries, like an API boundary that wants something other than seconds. - Floating point makes it easy to reason about infinity, which is something that time code wants to do a lot. Example: when would you like to timeout? Infinity please! This is the most elegant way of having an API support both a timeout variant and a no-timeout variant. - Floating point does well-understood things when math goes wrong, and these things are pretty well optimized to match what a mathematician would do when computing with real numbers represented using scientific notation with a finite number of significant digits. This means that time math under floating point looks like normal math. On the other hand, std::chrono time math looks like garbage because you have to always check for multiple possible UB corners whenever you touch large integers. Integers that represent time are very likely to be large and you don't have to do much to overflow them. At this time, based on the number of bugs we have already seen due to chrono overflows, I am not certain that we even understand what are all of the corner cases that we should even check for. This patch introduces a new set of timekeeping classes that are all based on double, and all internally use seconds. These classes support algebraic typing. The classes are: - Seconds: this is for measuring a duration. - WallTime: time since epoch according to a wall clock (aka real time clock). - MonotonicTime: time since epoch according to a monotonic clock. - ClockType: enum that says either Wall or Monotonic. - TimeWithDynamicClockType: a tuple of double and ClockType, which represents either a wall time or a monotonic time. All of these classes behave like C++ values and are cheap to copy around since they are very nearly POD. This supports comprehensive conversions between the various time types. Most of this is by way of algebra. Here are just some of the rules we recognize: WallTime = WallTime + Seconds Seconds = WallTime - WallTime MonotonicTime = MonotonicTime + Seconds etc... We support negative, infinite, and NaN times because math. We support conversions between MonotonicTime and WallTime, like: WallTime wt = mt.approximateWallTime() This is called this "approximate" because the only way to do it is to get the current time on both clocks and convert relative to that. Many of our APIs would be happy using whatever notion of time the user wanted to use. For those APIs, which includes Condition and ParkingLot, we have TimeWithDynamicClockType. You can automatically convert WallTime or MonotonicTime to TimeWithDynamicClockType. This means that if you use a WallTime with Condition::waitUntil, then Condition's internal logic for when it should wake up makes its decision based on the current WallTime - but if you use MonotonicTime then waitUntil will make its decision based on current MonotonicTime. This is a greater level of flexibility than chrono allowed, since chrono did not have the concept of a dynamic clock type. This patch does not include conversions between std::chrono and these new time classes, because past experience shows that we're quite bad at getting conversions between std::chrono and anything else right. Also, I didn't need such conversion code because this patch only converts code that transitively touches ParkingLot and Condition. It was easy to get all of that code onto the new time classes. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::start): * wtf/CMakeLists.txt: * wtf/ClockType.cpp: Added. (WTF::printInternal): * wtf/ClockType.h: Added. * wtf/Condition.h: (WTF::ConditionBase::waitUntil): (WTF::ConditionBase::waitFor): (WTF::ConditionBase::wait): (WTF::ConditionBase::waitUntilWallClockSeconds): Deleted. (WTF::ConditionBase::waitUntilMonotonicClockSeconds): Deleted. (WTF::ConditionBase::waitForSeconds): Deleted. (WTF::ConditionBase::waitForSecondsImpl): Deleted. (WTF::ConditionBase::waitForImpl): Deleted. (WTF::ConditionBase::absoluteFromRelative): Deleted. * wtf/CrossThreadQueue.h: (WTF::CrossThreadQueue<DataType>::waitForMessage): * wtf/CurrentTime.cpp: (WTF::sleep): * wtf/MessageQueue.h: (WTF::MessageQueue::infiniteTime): Deleted. * wtf/MonotonicTime.cpp: Added. (WTF::MonotonicTime::now): (WTF::MonotonicTime::approximateWallTime): (WTF::MonotonicTime::dump): (WTF::MonotonicTime::sleep): * wtf/MonotonicTime.h: Added. (WTF::MonotonicTime::MonotonicTime): (WTF::MonotonicTime::fromRawDouble): (WTF::MonotonicTime::infinity): (WTF::MonotonicTime::secondsSinceEpoch): (WTF::MonotonicTime::approximateMonotonicTime): (WTF::MonotonicTime::operator bool): (WTF::MonotonicTime::operator+): (WTF::MonotonicTime::operator-): (WTF::MonotonicTime::operator+=): (WTF::MonotonicTime::operator-=): (WTF::MonotonicTime::operator==): (WTF::MonotonicTime::operator!=): (WTF::MonotonicTime::operator<): (WTF::MonotonicTime::operator>): (WTF::MonotonicTime::operator<=): (WTF::MonotonicTime::operator>=): * wtf/ParkingLot.cpp: (WTF::ParkingLot::parkConditionallyImpl): (WTF::ParkingLot::unparkOne): (WTF::ParkingLot::unparkOneImpl): (WTF::ParkingLot::unparkCount): * wtf/ParkingLot.h: (WTF::ParkingLot::parkConditionally): (WTF::ParkingLot::compareAndPark): * wtf/Seconds.cpp: Added. (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::dump): (WTF::Seconds::sleep): * wtf/Seconds.h: Added. (WTF::Seconds::Seconds): (WTF::Seconds::value): (WTF::Seconds::seconds): (WTF::Seconds::milliseconds): (WTF::Seconds::microseconds): (WTF::Seconds::nanoseconds): (WTF::Seconds::fromMilliseconds): (WTF::Seconds::fromMicroseconds): (WTF::Seconds::fromNanoseconds): (WTF::Seconds::infinity): (WTF::Seconds::operator bool): (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::operator*): (WTF::Seconds::operator/): (WTF::Seconds::operator+=): (WTF::Seconds::operator-=): (WTF::Seconds::operator*=): (WTF::Seconds::operator/=): (WTF::Seconds::operator==): (WTF::Seconds::operator!=): (WTF::Seconds::operator<): (WTF::Seconds::operator>): (WTF::Seconds::operator<=): (WTF::Seconds::operator>=): * wtf/TimeWithDynamicClockType.cpp: Added. (WTF::TimeWithDynamicClockType::now): (WTF::TimeWithDynamicClockType::nowWithSameClock): (WTF::TimeWithDynamicClockType::wallTime): (WTF::TimeWithDynamicClockType::monotonicTime): (WTF::TimeWithDynamicClockType::approximateWallTime): (WTF::TimeWithDynamicClockType::approximateMonotonicTime): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator<): (WTF::TimeWithDynamicClockType::operator>): (WTF::TimeWithDynamicClockType::operator<=): (WTF::TimeWithDynamicClockType::operator>=): (WTF::TimeWithDynamicClockType::dump): (WTF::TimeWithDynamicClockType::sleep): * wtf/TimeWithDynamicClockType.h: Added. (WTF::TimeWithDynamicClockType::TimeWithDynamicClockType): (WTF::TimeWithDynamicClockType::fromRawDouble): (WTF::TimeWithDynamicClockType::secondsSinceEpoch): (WTF::TimeWithDynamicClockType::clockType): (WTF::TimeWithDynamicClockType::withSameClockAndRawDouble): (WTF::TimeWithDynamicClockType::operator bool): (WTF::TimeWithDynamicClockType::operator+): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator+=): (WTF::TimeWithDynamicClockType::operator-=): (WTF::TimeWithDynamicClockType::operator==): (WTF::TimeWithDynamicClockType::operator!=): * wtf/WallTime.cpp: Added. (WTF::WallTime::now): (WTF::WallTime::approximateMonotonicTime): (WTF::WallTime::dump): (WTF::WallTime::sleep): * wtf/WallTime.h: Added. (WTF::WallTime::WallTime): (WTF::WallTime::fromRawDouble): (WTF::WallTime::infinity): (WTF::WallTime::secondsSinceEpoch): (WTF::WallTime::approximateWallTime): (WTF::WallTime::operator bool): (WTF::WallTime::operator+): (WTF::WallTime::operator-): (WTF::WallTime::operator+=): (WTF::WallTime::operator-=): (WTF::WallTime::operator==): (WTF::WallTime::operator!=): (WTF::WallTime::operator<): (WTF::WallTime::operator>): (WTF::WallTime::operator<=): (WTF::WallTime::operator>=): * wtf/threads/BinarySemaphore.cpp: (WTF::BinarySemaphore::wait): * wtf/threads/BinarySemaphore.h: Tools: * TestWebKitAPI/CMakeLists.txt: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WTF/Condition.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: (TestWebKitAPI::ToUpperConverter::stopProducing): (TestWebKitAPI::ToUpperConverter::stopConsuming): * TestWebKitAPI/Tests/WTF/Time.cpp: Added. (WTF::operator<<): (TestWebKitAPI::TEST): Canonical link: https://commits.webkit.org/182152@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-05 03:02:39 +00:00
/*
* Copyright (C) 2016 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"
Use pragma once in WTF https://bugs.webkit.org/show_bug.cgi?id=190527 Reviewed by Chris Dumez. Source/WTF: We also need to consistently include wtf headers from within wtf so we can build wtf without symbol redefinition errors from including the copy in Source and the copy in the build directory. * wtf/ASCIICType.h: * wtf/Assertions.cpp: * wtf/Assertions.h: * wtf/Atomics.h: * wtf/AutomaticThread.cpp: * wtf/AutomaticThread.h: * wtf/BackwardsGraph.h: * wtf/Bag.h: * wtf/BagToHashMap.h: * wtf/BitVector.cpp: * wtf/BitVector.h: * wtf/Bitmap.h: * wtf/BloomFilter.h: * wtf/Box.h: * wtf/BubbleSort.h: * wtf/BumpPointerAllocator.h: * wtf/ByteOrder.h: * wtf/CPUTime.cpp: * wtf/CallbackAggregator.h: * wtf/CheckedArithmetic.h: * wtf/CheckedBoolean.h: * wtf/ClockType.cpp: * wtf/ClockType.h: * wtf/CommaPrinter.h: * wtf/CompilationThread.cpp: * wtf/CompilationThread.h: * wtf/Compiler.h: * wtf/ConcurrentPtrHashSet.cpp: * wtf/ConcurrentVector.h: * wtf/Condition.h: * wtf/CountingLock.cpp: * wtf/CrossThreadTaskHandler.cpp: * wtf/CryptographicUtilities.cpp: * wtf/CryptographicUtilities.h: * wtf/CryptographicallyRandomNumber.cpp: * wtf/CryptographicallyRandomNumber.h: * wtf/CurrentTime.cpp: * wtf/DataLog.cpp: * wtf/DataLog.h: * wtf/DateMath.cpp: * wtf/DateMath.h: * wtf/DecimalNumber.cpp: * wtf/DecimalNumber.h: * wtf/Deque.h: * wtf/DisallowCType.h: * wtf/Dominators.h: * wtf/DoublyLinkedList.h: * wtf/FastBitVector.cpp: * wtf/FastMalloc.cpp: * wtf/FastMalloc.h: * wtf/FeatureDefines.h: * wtf/FilePrintStream.cpp: * wtf/FilePrintStream.h: * wtf/FlipBytes.h: * wtf/FunctionDispatcher.cpp: * wtf/FunctionDispatcher.h: * wtf/GetPtr.h: * wtf/Gigacage.cpp: * wtf/GlobalVersion.cpp: * wtf/GraphNodeWorklist.h: * wtf/GregorianDateTime.cpp: * wtf/GregorianDateTime.h: * wtf/HashFunctions.h: * wtf/HashMap.h: * wtf/HashMethod.h: * wtf/HashSet.h: * wtf/HashTable.cpp: * wtf/HashTraits.h: * wtf/Indenter.h: * wtf/IndexSparseSet.h: * wtf/InlineASM.h: * wtf/Insertion.h: * wtf/IteratorAdaptors.h: * wtf/IteratorRange.h: * wtf/JSONValues.cpp: * wtf/JSValueMalloc.cpp: * wtf/LEBDecoder.h: * wtf/Language.cpp: * wtf/ListDump.h: * wtf/Lock.cpp: * wtf/Lock.h: * wtf/LockAlgorithm.h: * wtf/LockedPrintStream.cpp: * wtf/Locker.h: * wtf/MD5.cpp: * wtf/MD5.h: * wtf/MainThread.cpp: * wtf/MainThread.h: * wtf/MallocPtr.h: * wtf/MathExtras.h: * wtf/MediaTime.cpp: * wtf/MediaTime.h: * wtf/MemoryPressureHandler.cpp: * wtf/MessageQueue.h: * wtf/MetaAllocator.cpp: * wtf/MetaAllocator.h: * wtf/MetaAllocatorHandle.h: * wtf/MonotonicTime.cpp: * wtf/MonotonicTime.h: * wtf/NakedPtr.h: * wtf/NoLock.h: * wtf/NoTailCalls.h: * wtf/Noncopyable.h: * wtf/NumberOfCores.cpp: * wtf/NumberOfCores.h: * wtf/OSAllocator.h: * wtf/OSAllocatorPosix.cpp: * wtf/OSRandomSource.cpp: * wtf/OSRandomSource.h: * wtf/ObjcRuntimeExtras.h: * wtf/OrderMaker.h: * wtf/PackedIntVector.h: * wtf/PageAllocation.h: * wtf/PageBlock.cpp: * wtf/PageBlock.h: * wtf/PageReservation.h: * wtf/ParallelHelperPool.cpp: * wtf/ParallelHelperPool.h: * wtf/ParallelJobs.h: * wtf/ParallelJobsLibdispatch.h: * wtf/ParallelVectorIterator.h: * wtf/ParkingLot.cpp: * wtf/ParkingLot.h: * wtf/Platform.h: * wtf/PointerComparison.h: * wtf/Poisoned.cpp: * wtf/PrintStream.cpp: * wtf/PrintStream.h: * wtf/ProcessID.h: * wtf/ProcessPrivilege.cpp: * wtf/RAMSize.cpp: * wtf/RAMSize.h: * wtf/RandomDevice.cpp: * wtf/RandomNumber.cpp: * wtf/RandomNumber.h: * wtf/RandomNumberSeed.h: * wtf/RangeSet.h: * wtf/RawPointer.h: * wtf/ReadWriteLock.cpp: * wtf/RedBlackTree.h: * wtf/Ref.h: * wtf/RefCountedArray.h: * wtf/RefCountedLeakCounter.cpp: * wtf/RefCountedLeakCounter.h: * wtf/RefCounter.h: * wtf/RefPtr.h: * wtf/RetainPtr.h: * wtf/RunLoop.cpp: * wtf/RunLoop.h: * wtf/RunLoopTimer.h: * wtf/RunLoopTimerCF.cpp: * wtf/SHA1.cpp: * wtf/SHA1.h: * wtf/SaturatedArithmetic.h: (saturatedSubtraction): * wtf/SchedulePair.h: * wtf/SchedulePairCF.cpp: * wtf/SchedulePairMac.mm: * wtf/ScopedLambda.h: * wtf/Seconds.cpp: * wtf/Seconds.h: * wtf/SegmentedVector.h: * wtf/SentinelLinkedList.h: * wtf/SharedTask.h: * wtf/SimpleStats.h: * wtf/SingleRootGraph.h: * wtf/SinglyLinkedList.h: * wtf/SixCharacterHash.cpp: * wtf/SixCharacterHash.h: * wtf/SmallPtrSet.h: * wtf/Spectrum.h: * wtf/StackBounds.cpp: * wtf/StackBounds.h: * wtf/StackStats.cpp: * wtf/StackStats.h: * wtf/StackTrace.cpp: * wtf/StdLibExtras.h: * wtf/StreamBuffer.h: * wtf/StringHashDumpContext.h: * wtf/StringPrintStream.cpp: * wtf/StringPrintStream.h: * wtf/ThreadGroup.cpp: * wtf/ThreadMessage.cpp: * wtf/ThreadSpecific.h: * wtf/Threading.cpp: * wtf/Threading.h: * wtf/ThreadingPrimitives.h: * wtf/ThreadingPthreads.cpp: * wtf/TimeWithDynamicClockType.cpp: * wtf/TimeWithDynamicClockType.h: * wtf/TimingScope.cpp: * wtf/TinyLRUCache.h: * wtf/TinyPtrSet.h: * wtf/TriState.h: * wtf/TypeCasts.h: * wtf/UUID.cpp: * wtf/UnionFind.h: * wtf/VMTags.h: * wtf/ValueCheck.h: * wtf/Vector.h: * wtf/VectorTraits.h: * wtf/WallTime.cpp: * wtf/WallTime.h: * wtf/WeakPtr.h: * wtf/WeakRandom.h: * wtf/WordLock.cpp: * wtf/WordLock.h: * wtf/WorkQueue.cpp: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: * wtf/cf/LanguageCF.cpp: * wtf/cf/RunLoopCF.cpp: * wtf/cocoa/Entitlements.mm: * wtf/cocoa/MachSendRight.cpp: * wtf/cocoa/MainThreadCocoa.mm: * wtf/cocoa/MemoryFootprintCocoa.cpp: * wtf/cocoa/WorkQueueCocoa.cpp: * wtf/dtoa.cpp: * wtf/dtoa.h: * wtf/ios/WebCoreThread.cpp: * wtf/ios/WebCoreThread.h: * wtf/mac/AppKitCompatibilityDeclarations.h: * wtf/mac/DeprecatedSymbolsUsedBySafari.mm: * wtf/mbmalloc.cpp: * wtf/persistence/PersistentCoders.cpp: * wtf/persistence/PersistentDecoder.cpp: * wtf/persistence/PersistentEncoder.cpp: * wtf/spi/cf/CFBundleSPI.h: * wtf/spi/darwin/CommonCryptoSPI.h: * wtf/text/ASCIIFastPath.h: * wtf/text/ASCIILiteral.cpp: * wtf/text/AtomicString.cpp: * wtf/text/AtomicString.h: * wtf/text/AtomicStringHash.h: * wtf/text/AtomicStringImpl.cpp: * wtf/text/AtomicStringImpl.h: * wtf/text/AtomicStringTable.cpp: * wtf/text/AtomicStringTable.h: * wtf/text/Base64.cpp: * wtf/text/CString.cpp: * wtf/text/CString.h: * wtf/text/ConversionMode.h: * wtf/text/ExternalStringImpl.cpp: * wtf/text/IntegerToStringConversion.h: * wtf/text/LChar.h: * wtf/text/LineEnding.cpp: * wtf/text/StringBuffer.h: * wtf/text/StringBuilder.cpp: * wtf/text/StringBuilder.h: * wtf/text/StringBuilderJSON.cpp: * wtf/text/StringCommon.h: * wtf/text/StringConcatenate.h: * wtf/text/StringHash.h: * wtf/text/StringImpl.cpp: * wtf/text/StringImpl.h: * wtf/text/StringOperators.h: * wtf/text/StringView.cpp: * wtf/text/StringView.h: * wtf/text/SymbolImpl.cpp: * wtf/text/SymbolRegistry.cpp: * wtf/text/SymbolRegistry.h: * wtf/text/TextBreakIterator.cpp: * wtf/text/TextBreakIterator.h: * wtf/text/TextBreakIteratorInternalICU.h: * wtf/text/TextPosition.h: * wtf/text/TextStream.cpp: * wtf/text/UniquedStringImpl.h: * wtf/text/WTFString.cpp: * wtf/text/WTFString.h: * wtf/text/cocoa/StringCocoa.mm: * wtf/text/cocoa/StringViewCocoa.mm: * wtf/text/cocoa/TextBreakIteratorInternalICUCocoa.cpp: * wtf/text/icu/UTextProvider.cpp: * wtf/text/icu/UTextProvider.h: * wtf/text/icu/UTextProviderLatin1.cpp: * wtf/text/icu/UTextProviderLatin1.h: * wtf/text/icu/UTextProviderUTF16.cpp: * wtf/text/icu/UTextProviderUTF16.h: * wtf/threads/BinarySemaphore.cpp: * wtf/threads/BinarySemaphore.h: * wtf/threads/Signals.cpp: * wtf/unicode/CharacterNames.h: * wtf/unicode/Collator.h: * wtf/unicode/CollatorDefault.cpp: * wtf/unicode/UTF8.cpp: * wtf/unicode/UTF8.h: Tools: Put WorkQueue in namespace DRT so it does not conflict with WTF::WorkQueue. * DumpRenderTree/TestRunner.cpp: (TestRunner::queueLoadHTMLString): (TestRunner::queueLoadAlternateHTMLString): (TestRunner::queueBackNavigation): (TestRunner::queueForwardNavigation): (TestRunner::queueLoadingScript): (TestRunner::queueNonLoadingScript): (TestRunner::queueReload): * DumpRenderTree/WorkQueue.cpp: (WorkQueue::singleton): Deleted. (WorkQueue::WorkQueue): Deleted. (WorkQueue::queue): Deleted. (WorkQueue::dequeue): Deleted. (WorkQueue::count): Deleted. (WorkQueue::clear): Deleted. (WorkQueue::processWork): Deleted. * DumpRenderTree/WorkQueue.h: (WorkQueue::setFrozen): Deleted. * DumpRenderTree/WorkQueueItem.h: * DumpRenderTree/mac/DumpRenderTree.mm: (runTest): * DumpRenderTree/mac/FrameLoadDelegate.mm: (-[FrameLoadDelegate processWork:]): (-[FrameLoadDelegate webView:locationChangeDone:forDataSource:]): * DumpRenderTree/mac/TestRunnerMac.mm: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): * DumpRenderTree/win/DumpRenderTree.cpp: (runTest): * DumpRenderTree/win/FrameLoadDelegate.cpp: (FrameLoadDelegate::processWork): (FrameLoadDelegate::locationChangeDone): * DumpRenderTree/win/TestRunnerWin.cpp: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): Canonical link: https://commits.webkit.org/205473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237099 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-15 14:24:49 +00:00
#include <wtf/TimeWithDynamicClockType.h>
WTF::ParkingLot should stop using std::chrono because std::chrono::duration casts are prone to overflows https://bugs.webkit.org/show_bug.cgi?id=152045 Reviewed by Andy Estes. Source/JavaScriptCore: Probably the nicest example of why this patch is a good idea is the change in AtomicsObject.cpp. * jit/ICStats.cpp: (JSC::ICStats::ICStats): * runtime/AtomicsObject.cpp: (JSC::atomicsFuncWait): Source/WebCore: No new layout tests because no new behavior. The new WTF time classes have some unit tests in TestWebKitAPI. * fileapi/ThreadableBlobRegistry.cpp: (WebCore::ThreadableBlobRegistry::blobSize): * platform/MainThreadSharedTimer.h: * platform/SharedTimer.h: * platform/ThreadTimers.cpp: (WebCore::ThreadTimers::updateSharedTimer): * platform/cf/MainThreadSharedTimerCF.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/efl/MainThreadSharedTimerEfl.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/glib/MainThreadSharedTimerGLib.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/win/MainThreadSharedTimerWin.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * workers/WorkerRunLoop.cpp: (WebCore::WorkerRunLoop::runInMode): Source/WebKit2: * Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageState::wait): (IPC::Connection::sendMessage): (IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting): (IPC::Connection::waitForMessage): (IPC::Connection::sendSyncMessage): (IPC::Connection::waitForSyncReply): * Platform/IPC/Connection.h: (IPC::Connection::sendSync): (IPC::Connection::waitForAndDispatchImmediately): * Platform/IPC/MessageSender.h: (IPC::MessageSender::sendSync): * UIProcess/ChildProcessProxy.h: (WebKit::ChildProcessProxy::sendSync): * UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): * UIProcess/Storage/StorageManager.cpp: (WebKit::StorageManager::applicationWillTerminate): * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::sendProcessWillSuspendImminently): * UIProcess/WebResourceLoadStatisticsStore.cpp: (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate): * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (-[WKOneShotDisplayLinkHandler displayLinkFired:]): (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay): (WebKit::RemoteLayerTreeDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/WKImmediateActionController.mm: (-[WKImmediateActionController immediateActionRecognizerWillBeginAnimation:]): * UIProcess/mac/WebPageProxyMac.mm: (WebKit::WebPageProxy::stringSelectionForPasteboard): (WebKit::WebPageProxy::dataSelectionForPasteboard): (WebKit::WebPageProxy::readSelectionFromPasteboard): (WebKit::WebPageProxy::shouldDelayWindowOrderingForEvent): (WebKit::WebPageProxy::acceptsFirstMouse): * WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): (WebKit::WebChromeClient::runJavaScriptAlert): (WebKit::WebChromeClient::runJavaScriptConfirm): (WebKit::WebChromeClient::runJavaScriptPrompt): (WebKit::WebChromeClient::print): (WebKit::WebChromeClient::exceededDatabaseQuota): (WebKit::WebChromeClient::reachedApplicationCacheOriginQuota): * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::postSynchronousMessageForTesting): Source/WTF: We used to use 'double' for all time measurements. Sometimes it was milliseconds, sometimes it was seconds. Sometimes we measured a span of time, sometimes we spoke of time since some epoch. When we spoke of time since epoch, we either used a monotonic clock or a wall clock. The type - always 'double' - never told us what kind of time we had, even though there were roughly six of them (sec interval, ms interval, sec since epoch on wall, ms since epoch on wall, sec since epoch monotonic, ms since epoch monotonic). At some point, we thought that it would be a good idea to replace these doubles with std::chrono. But since replacing some things with std::chrono, we found it to be terribly inconvenient: - Outrageous API. I never want to say std::chrono::milliseconds(blah). I never want to say std::chrono::steady_clock::timepoint. The syntax for duration_cast is ugly, and ideally duration_cast would not even be a thing. - No overflow protection. std::chrono uses integers by default and using anything else is clumsy. But the integer math is done without regard for the rough edges of integer math, so any cast between std::chrono types risks overflow. Any comparison risks overflow because it may do conversions silently. We have even found bugs where some C++ implementations had more overflows than others, which ends up being a special kind of hell. In many cases, the overflow also has nasal demons. It's an error to represent time using integers. It would have been excusable back when floating point math was not guaranteed to be supported on all platforms, but that would have been a long time ago. Time is a continuous, infinite concept and it's a perfect fit for floating point: - Floating point preserves precision under multiplication in all but extreme cases, so using floating point for time means that unit conversions are almost completely lossless. This means that we don't have to think very hard about what units to use. In this patch, we use seconds almost everywhere. We only convert at boundaries, like an API boundary that wants something other than seconds. - Floating point makes it easy to reason about infinity, which is something that time code wants to do a lot. Example: when would you like to timeout? Infinity please! This is the most elegant way of having an API support both a timeout variant and a no-timeout variant. - Floating point does well-understood things when math goes wrong, and these things are pretty well optimized to match what a mathematician would do when computing with real numbers represented using scientific notation with a finite number of significant digits. This means that time math under floating point looks like normal math. On the other hand, std::chrono time math looks like garbage because you have to always check for multiple possible UB corners whenever you touch large integers. Integers that represent time are very likely to be large and you don't have to do much to overflow them. At this time, based on the number of bugs we have already seen due to chrono overflows, I am not certain that we even understand what are all of the corner cases that we should even check for. This patch introduces a new set of timekeeping classes that are all based on double, and all internally use seconds. These classes support algebraic typing. The classes are: - Seconds: this is for measuring a duration. - WallTime: time since epoch according to a wall clock (aka real time clock). - MonotonicTime: time since epoch according to a monotonic clock. - ClockType: enum that says either Wall or Monotonic. - TimeWithDynamicClockType: a tuple of double and ClockType, which represents either a wall time or a monotonic time. All of these classes behave like C++ values and are cheap to copy around since they are very nearly POD. This supports comprehensive conversions between the various time types. Most of this is by way of algebra. Here are just some of the rules we recognize: WallTime = WallTime + Seconds Seconds = WallTime - WallTime MonotonicTime = MonotonicTime + Seconds etc... We support negative, infinite, and NaN times because math. We support conversions between MonotonicTime and WallTime, like: WallTime wt = mt.approximateWallTime() This is called this "approximate" because the only way to do it is to get the current time on both clocks and convert relative to that. Many of our APIs would be happy using whatever notion of time the user wanted to use. For those APIs, which includes Condition and ParkingLot, we have TimeWithDynamicClockType. You can automatically convert WallTime or MonotonicTime to TimeWithDynamicClockType. This means that if you use a WallTime with Condition::waitUntil, then Condition's internal logic for when it should wake up makes its decision based on the current WallTime - but if you use MonotonicTime then waitUntil will make its decision based on current MonotonicTime. This is a greater level of flexibility than chrono allowed, since chrono did not have the concept of a dynamic clock type. This patch does not include conversions between std::chrono and these new time classes, because past experience shows that we're quite bad at getting conversions between std::chrono and anything else right. Also, I didn't need such conversion code because this patch only converts code that transitively touches ParkingLot and Condition. It was easy to get all of that code onto the new time classes. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::start): * wtf/CMakeLists.txt: * wtf/ClockType.cpp: Added. (WTF::printInternal): * wtf/ClockType.h: Added. * wtf/Condition.h: (WTF::ConditionBase::waitUntil): (WTF::ConditionBase::waitFor): (WTF::ConditionBase::wait): (WTF::ConditionBase::waitUntilWallClockSeconds): Deleted. (WTF::ConditionBase::waitUntilMonotonicClockSeconds): Deleted. (WTF::ConditionBase::waitForSeconds): Deleted. (WTF::ConditionBase::waitForSecondsImpl): Deleted. (WTF::ConditionBase::waitForImpl): Deleted. (WTF::ConditionBase::absoluteFromRelative): Deleted. * wtf/CrossThreadQueue.h: (WTF::CrossThreadQueue<DataType>::waitForMessage): * wtf/CurrentTime.cpp: (WTF::sleep): * wtf/MessageQueue.h: (WTF::MessageQueue::infiniteTime): Deleted. * wtf/MonotonicTime.cpp: Added. (WTF::MonotonicTime::now): (WTF::MonotonicTime::approximateWallTime): (WTF::MonotonicTime::dump): (WTF::MonotonicTime::sleep): * wtf/MonotonicTime.h: Added. (WTF::MonotonicTime::MonotonicTime): (WTF::MonotonicTime::fromRawDouble): (WTF::MonotonicTime::infinity): (WTF::MonotonicTime::secondsSinceEpoch): (WTF::MonotonicTime::approximateMonotonicTime): (WTF::MonotonicTime::operator bool): (WTF::MonotonicTime::operator+): (WTF::MonotonicTime::operator-): (WTF::MonotonicTime::operator+=): (WTF::MonotonicTime::operator-=): (WTF::MonotonicTime::operator==): (WTF::MonotonicTime::operator!=): (WTF::MonotonicTime::operator<): (WTF::MonotonicTime::operator>): (WTF::MonotonicTime::operator<=): (WTF::MonotonicTime::operator>=): * wtf/ParkingLot.cpp: (WTF::ParkingLot::parkConditionallyImpl): (WTF::ParkingLot::unparkOne): (WTF::ParkingLot::unparkOneImpl): (WTF::ParkingLot::unparkCount): * wtf/ParkingLot.h: (WTF::ParkingLot::parkConditionally): (WTF::ParkingLot::compareAndPark): * wtf/Seconds.cpp: Added. (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::dump): (WTF::Seconds::sleep): * wtf/Seconds.h: Added. (WTF::Seconds::Seconds): (WTF::Seconds::value): (WTF::Seconds::seconds): (WTF::Seconds::milliseconds): (WTF::Seconds::microseconds): (WTF::Seconds::nanoseconds): (WTF::Seconds::fromMilliseconds): (WTF::Seconds::fromMicroseconds): (WTF::Seconds::fromNanoseconds): (WTF::Seconds::infinity): (WTF::Seconds::operator bool): (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::operator*): (WTF::Seconds::operator/): (WTF::Seconds::operator+=): (WTF::Seconds::operator-=): (WTF::Seconds::operator*=): (WTF::Seconds::operator/=): (WTF::Seconds::operator==): (WTF::Seconds::operator!=): (WTF::Seconds::operator<): (WTF::Seconds::operator>): (WTF::Seconds::operator<=): (WTF::Seconds::operator>=): * wtf/TimeWithDynamicClockType.cpp: Added. (WTF::TimeWithDynamicClockType::now): (WTF::TimeWithDynamicClockType::nowWithSameClock): (WTF::TimeWithDynamicClockType::wallTime): (WTF::TimeWithDynamicClockType::monotonicTime): (WTF::TimeWithDynamicClockType::approximateWallTime): (WTF::TimeWithDynamicClockType::approximateMonotonicTime): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator<): (WTF::TimeWithDynamicClockType::operator>): (WTF::TimeWithDynamicClockType::operator<=): (WTF::TimeWithDynamicClockType::operator>=): (WTF::TimeWithDynamicClockType::dump): (WTF::TimeWithDynamicClockType::sleep): * wtf/TimeWithDynamicClockType.h: Added. (WTF::TimeWithDynamicClockType::TimeWithDynamicClockType): (WTF::TimeWithDynamicClockType::fromRawDouble): (WTF::TimeWithDynamicClockType::secondsSinceEpoch): (WTF::TimeWithDynamicClockType::clockType): (WTF::TimeWithDynamicClockType::withSameClockAndRawDouble): (WTF::TimeWithDynamicClockType::operator bool): (WTF::TimeWithDynamicClockType::operator+): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator+=): (WTF::TimeWithDynamicClockType::operator-=): (WTF::TimeWithDynamicClockType::operator==): (WTF::TimeWithDynamicClockType::operator!=): * wtf/WallTime.cpp: Added. (WTF::WallTime::now): (WTF::WallTime::approximateMonotonicTime): (WTF::WallTime::dump): (WTF::WallTime::sleep): * wtf/WallTime.h: Added. (WTF::WallTime::WallTime): (WTF::WallTime::fromRawDouble): (WTF::WallTime::infinity): (WTF::WallTime::secondsSinceEpoch): (WTF::WallTime::approximateWallTime): (WTF::WallTime::operator bool): (WTF::WallTime::operator+): (WTF::WallTime::operator-): (WTF::WallTime::operator+=): (WTF::WallTime::operator-=): (WTF::WallTime::operator==): (WTF::WallTime::operator!=): (WTF::WallTime::operator<): (WTF::WallTime::operator>): (WTF::WallTime::operator<=): (WTF::WallTime::operator>=): * wtf/threads/BinarySemaphore.cpp: (WTF::BinarySemaphore::wait): * wtf/threads/BinarySemaphore.h: Tools: * TestWebKitAPI/CMakeLists.txt: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WTF/Condition.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: (TestWebKitAPI::ToUpperConverter::stopProducing): (TestWebKitAPI::ToUpperConverter::stopConsuming): * TestWebKitAPI/Tests/WTF/Time.cpp: Added. (WTF::operator<<): (TestWebKitAPI::TEST): Canonical link: https://commits.webkit.org/182152@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-05 03:02:39 +00:00
The GC should be optionally concurrent and disabled by default https://bugs.webkit.org/show_bug.cgi?id=164454 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This started out as a patch to have the GC scan the stack at the end, and then the outage happened and I decided to pick a more aggresive target: give the GC a concurrent mode that can be enabled at runtime, and whose only effect is that it turns on the ResumeTheWorldScope. This gives our GC a really intuitive workflow: by default, the GC thread is running solo with the world stopped and the parallel markers converged and waiting. We have a parallel work scope to enable the parallel markers and now we have a ResumeTheWorldScope that will optionally resume the world and then stop it again. It's easy to make a concurrent GC that always instantly crashes. I can't promise that this one won't do that when you run it. I set a specific goal: I wanted to do >10 concurrent GCs in debug mode with generations, optimizing JITs, and parallel marking disabled. To reach this milestone, I needed to do a bunch of stuff: - The mutator needs a separate mark stack for the barrier, since it will mutate this stack concurrently to the collector's slot visitors. - The use of CellState to indicate whether an object is being scanned the first time or a subsequent time was racy. It fails spectacularly when a barrier is fired at the same time as visitChildren is running or if the barrier runs at the same time as the GC marks the same object. So, I split SlotVisitor's mark stacks. It's now the case that you know why you're being scanned by looking at which stack you came off of. - All of root marking must be in the collector fixpoint. I renamed markRoots to markToFixpoint. They say concurrency is hard, but the collector looks more intuitive this way. We never gained anything from forcing people to make a choice between scanning something in the fixpoint versus outside of it. Because root scanning is cheap, we can afford to do it repeatedly, which means all root scanning can now do constraint-based marking (like: I'll mark you if that thing is marked). - JSObject::visitChildren's scanning of the butterfly raced with property additions, indexed storage transitions and resizing, and a bunch of miscellaneous dirty butterfly reshaping functions - like the one that flattens a dictionary and some sneaky ArrayStorage transformations. Many of these can be fixed by using store-store fences in the mutator and load-load fences in the collector. I've adopted the rule that the collector must always see either a butterfly and structure that match or a newer butterfly with an older structure, where their age is just one transition apart. This can be achieved with fences. For the cases where it breaks down, I added a lock to every JSCell. This is a full-fledged WTF lock that we sneak into two available bits in the indexingType. See the WTF ChangeLog for details. The mutator fencing rules are as follows: - Store-store fence before and after setting the butterfly. - Store-store fence before setting structure if you had changed the shape of the butterfly. - Store-store fence after initializing all fields in an allocation. - A dictionary Structure can change in strange ways while the GC is trying to scan it. So, JSObject::visitChildren will now grab the object's structure's lock if the object's structure is a dictionary. Dictionary structures are 1:1 with their object, so this does not reduce GC parallelism (super unlikely that the GC will simultaneously scan an object from two threads). - The GC can blow away a Structure's property table at any time. As a small consolation, it's now holding the Structure's lock when it does so. But there was tons of code in Structure that uses DeferGC to prevent the GC from blowing away the property table. This doesn't work with concurrent GC, since DeferGC only means that the GC won't run its safepoint (i.e. stop-the-world code) in the DeferGC region. It will still do marking and it was the Structure::visitChildren that would delete the table. It turns out that Structure's reliance on the property table not being deleted was the product of code rot. We already had functions that would materialize the table on demand. We were simply making the mistake of saying: structure->materializePropertyMap(); ... structure->propertyTable()->things Instead of saying: PropertyTable* table = structure->ensurePropertyTable(); ... table->things Switching the code to use the latter idiom allowed me to simplify the code a lot while fixing the race. - The LLInt's get_by_val handling was broken because the indexing shape constants were wrong. Once I started putting more things into the IndexingType, that started causing crashes for me. So I fixed LLInt. That turned out to be a lot of work, since that code had rotted in subtle ways. This is a speed-up in SunSpider, probably because of the LLInt fix. This is neutral on Octane and Kraken. It's a smaller slow-down on LongSpider, but I think we can ignore that (we don't view LongSpider as an official benchmark). By default, the concurrent GC is disabled: in all of the places where it would have resumed the world to run marking concurrently to the mutator, it will just skip the resume step. When you enable concurrent GC (--useConcurrentGC=true), it can sometimes run Octane/splay to completion. It seems to perform quite well: on my machine, it improves both splay-throughput and splay-latency. It's probably unstable for other programs. * API/JSVirtualMachine.mm: (-[JSVirtualMachine isOldExternalObject:]): * assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::storeFence): * bytecode/InlineAccess.cpp: (JSC::InlineAccess::dumpCacheSizesAndCrash): (JSC::InlineAccess::generateSelfPropertyAccess): (JSC::InlineAccess::generateArrayLength): * bytecode/ObjectAllocationProfile.h: (JSC::ObjectAllocationProfile::offsetOfInlineCapacity): (JSC::ObjectAllocationProfile::ObjectAllocationProfile): (JSC::ObjectAllocationProfile::initialize): (JSC::ObjectAllocationProfile::inlineCapacity): (JSC::ObjectAllocationProfile::clear): * bytecode/PolymorphicAccess.cpp: (JSC::AccessCase::generateWithGuard): (JSC::AccessCase::generateImpl): * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGOSRExitCompiler32_64.cpp: (JSC::DFG::OSRExitCompiler::compileExit): * dfg/DFGOSRExitCompiler64.cpp: (JSC::DFG::OSRExitCompiler::compileExit): * dfg/DFGOperations.cpp: * dfg/DFGPlan.cpp: (JSC::DFG::Plan::markCodeBlocks): (JSC::DFG::Plan::rememberCodeBlocks): * dfg/DFGPlan.h: * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::emitAllocateRawObject): (JSC::DFG::SpeculativeJIT::checkArray): (JSC::DFG::SpeculativeJIT::arrayify): (JSC::DFG::SpeculativeJIT::compileMakeRope): (JSC::DFG::SpeculativeJIT::compileNewFunctionCommon): (JSC::DFG::SpeculativeJIT::compileCreateActivation): (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments): (JSC::DFG::SpeculativeJIT::compileSpread): (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): (JSC::DFG::SpeculativeJIT::compileNewStringObject): (JSC::DFG::SpeculativeJIT::compileNewTypedArray): (JSC::DFG::SpeculativeJIT::compileStoreBarrier): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): * dfg/DFGTierUpCheckInjectionPhase.cpp: (JSC::DFG::TierUpCheckInjectionPhase::run): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::markCodeBlocks): (JSC::DFG::Worklist::rememberCodeBlocks): (JSC::DFG::markCodeBlocks): (JSC::DFG::completeAllPlansForVM): (JSC::DFG::rememberCodeBlocks): * dfg/DFGWorklist.h: * ftl/FTLAbstractHeapRepository.cpp: (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository): (JSC::FTL::AbstractHeapRepository::computeRangesAndDecorateInstructions): * ftl/FTLAbstractHeapRepository.h: * ftl/FTLJITCode.cpp: (JSC::FTL::JITCode::~JITCode): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compilePutStructure): (JSC::FTL::DFG::LowerDFGToB3::compileCreateActivation): (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction): (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments): (JSC::FTL::DFG::LowerDFGToB3::compileCreateRest): (JSC::FTL::DFG::LowerDFGToB3::compileNewObject): (JSC::FTL::DFG::LowerDFGToB3::compileNewArray): (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread): (JSC::FTL::DFG::LowerDFGToB3::compileSpread): (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayBuffer): (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize): (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): (JSC::FTL::DFG::LowerDFGToB3::compileMakeRope): (JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset): (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeCreateActivation): (JSC::FTL::DFG::LowerDFGToB3::splatWords): (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorage): (JSC::FTL::DFG::LowerDFGToB3::reallocatePropertyStorage): (JSC::FTL::DFG::LowerDFGToB3::allocateObject): (JSC::FTL::DFG::LowerDFGToB3::isArrayType): (JSC::FTL::DFG::LowerDFGToB3::emitStoreBarrier): (JSC::FTL::DFG::LowerDFGToB3::mutatorFence): (JSC::FTL::DFG::LowerDFGToB3::setButterfly): * ftl/FTLOSRExitCompiler.cpp: (JSC::FTL::compileStub): * ftl/FTLOutput.cpp: (JSC::FTL::Output::signExt32ToPtr): (JSC::FTL::Output::fence): * ftl/FTLOutput.h: * heap/CellState.h: * heap/GCSegmentedArray.h: * heap/Heap.cpp: (JSC::Heap::ResumeTheWorldScope::ResumeTheWorldScope): (JSC::Heap::ResumeTheWorldScope::~ResumeTheWorldScope): (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::harvestWeakReferences): (JSC::Heap::finalizeUnconditionalFinalizers): (JSC::Heap::completeAllJITPlans): (JSC::Heap::markToFixpoint): (JSC::Heap::gatherStackRoots): (JSC::Heap::beginMarking): (JSC::Heap::visitConservativeRoots): (JSC::Heap::visitCompilerWorklistWeakReferences): (JSC::Heap::updateObjectCounts): (JSC::Heap::endMarking): (JSC::Heap::addToRememberedSet): (JSC::Heap::collectInThread): (JSC::Heap::stopTheWorld): (JSC::Heap::resumeTheWorld): (JSC::Heap::setGCDidJIT): (JSC::Heap::setNeedFinalize): (JSC::Heap::setMutatorWaiting): (JSC::Heap::clearMutatorWaiting): (JSC::Heap::finalize): (JSC::Heap::flushWriteBarrierBuffer): (JSC::Heap::writeBarrierSlowPath): (JSC::Heap::canCollect): (JSC::Heap::reportExtraMemoryVisited): (JSC::Heap::reportExternalMemoryVisited): (JSC::Heap::notifyIsSafeToCollect): (JSC::Heap::markRoots): Deleted. (JSC::Heap::visitExternalRememberedSet): Deleted. (JSC::Heap::visitSmallStrings): Deleted. (JSC::Heap::visitProtectedObjects): Deleted. (JSC::Heap::visitArgumentBuffers): Deleted. (JSC::Heap::visitException): Deleted. (JSC::Heap::visitStrongHandles): Deleted. (JSC::Heap::visitHandleStack): Deleted. (JSC::Heap::visitSamplingProfiler): Deleted. (JSC::Heap::visitTypeProfiler): Deleted. (JSC::Heap::visitShadowChicken): Deleted. (JSC::Heap::traceCodeBlocksAndJITStubRoutines): Deleted. (JSC::Heap::visitWeakHandles): Deleted. (JSC::Heap::flushOldStructureIDTables): Deleted. (JSC::Heap::stopAllocation): Deleted. * heap/Heap.h: (JSC::Heap::collectorSlotVisitor): (JSC::Heap::mutatorMarkStack): (JSC::Heap::mutatorShouldBeFenced): (JSC::Heap::addressOfMutatorShouldBeFenced): (JSC::Heap::slotVisitor): Deleted. (JSC::Heap::notifyIsSafeToCollect): Deleted. (JSC::Heap::barrierShouldBeFenced): Deleted. (JSC::Heap::addressOfBarrierShouldBeFenced): Deleted. * heap/MarkStack.cpp: (JSC::MarkStackArray::transferTo): * heap/MarkStack.h: * heap/MarkedAllocator.cpp: (JSC::MarkedAllocator::tryAllocateIn): * heap/MarkedBlock.cpp: (JSC::MarkedBlock::MarkedBlock): (JSC::MarkedBlock::Handle::specializedSweep): (JSC::MarkedBlock::Handle::sweep): (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): (JSC::MarkedBlock::Handle::stopAllocating): (JSC::MarkedBlock::Handle::resumeAllocating): (JSC::MarkedBlock::aboutToMarkSlow): (JSC::MarkedBlock::Handle::didConsumeFreeList): (JSC::SetNewlyAllocatedFunctor::SetNewlyAllocatedFunctor): Deleted. (JSC::SetNewlyAllocatedFunctor::operator()): Deleted. * heap/MarkedBlock.h: * heap/MarkedSpace.cpp: (JSC::MarkedSpace::resumeAllocating): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::SlotVisitor): (JSC::SlotVisitor::~SlotVisitor): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::clearMarkStacks): (JSC::SlotVisitor::appendJSCellOrAuxiliary): (JSC::SlotVisitor::setMarkedAndAppendToMarkStack): (JSC::SlotVisitor::appendToMarkStack): (JSC::SlotVisitor::appendToMutatorMarkStack): (JSC::SlotVisitor::visitChildren): (JSC::SlotVisitor::donateKnownParallel): (JSC::SlotVisitor::drain): (JSC::SlotVisitor::drainFromShared): (JSC::SlotVisitor::containsOpaqueRoot): (JSC::SlotVisitor::donateAndDrain): (JSC::SlotVisitor::mergeOpaqueRoots): (JSC::SlotVisitor::dump): (JSC::SlotVisitor::clearMarkStack): Deleted. (JSC::SlotVisitor::opaqueRootCount): Deleted. * heap/SlotVisitor.h: (JSC::SlotVisitor::collectorMarkStack): (JSC::SlotVisitor::mutatorMarkStack): (JSC::SlotVisitor::isEmpty): (JSC::SlotVisitor::bytesVisited): (JSC::SlotVisitor::markStack): Deleted. (JSC::SlotVisitor::bytesCopied): Deleted. * heap/SlotVisitorInlines.h: (JSC::SlotVisitor::reportExtraMemoryVisited): (JSC::SlotVisitor::reportExternalMemoryVisited): * jit/AssemblyHelpers.cpp: (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): * jit/AssemblyHelpers.h: (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): (JSC::AssemblyHelpers::barrierStoreLoadFence): (JSC::AssemblyHelpers::mutatorFence): (JSC::AssemblyHelpers::storeButterfly): (JSC::AssemblyHelpers::jumpIfMutatorFenceNotNeeded): (JSC::AssemblyHelpers::emitInitializeInlineStorage): (JSC::AssemblyHelpers::emitInitializeOutOfLineStorage): (JSC::AssemblyHelpers::jumpIfBarrierStoreLoadFenceNotNeeded): Deleted. * jit/JITInlines.h: (JSC::JIT::emitArrayProfilingSiteWithCell): * jit/JITOperations.cpp: * jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_put_to_scope): (JSC::JIT::emit_op_put_to_arguments): * llint/LLIntData.cpp: (JSC::LLInt::Data::performAssertions): * llint/LowLevelInterpreter.asm: * llint/LowLevelInterpreter64.asm: * runtime/ButterflyInlines.h: (JSC::Butterfly::create): (JSC::Butterfly::createOrGrowPropertyStorage): * runtime/ConcurrentJITLock.h: (JSC::GCSafeConcurrentJITLocker::NoDefer::NoDefer): Deleted. * runtime/GenericArgumentsInlines.h: (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex): (JSC::GenericArguments<Type>::putByIndex): * runtime/IndexingType.h: * runtime/JSArray.cpp: (JSC::JSArray::unshiftCountSlowCase): (JSC::JSArray::unshiftCountWithArrayStorage): * runtime/JSCell.h: (JSC::JSCell::InternalLocker::InternalLocker): (JSC::JSCell::InternalLocker::~InternalLocker): (JSC::JSCell::atomicCompareExchangeCellStateWeakRelaxed): (JSC::JSCell::atomicCompareExchangeCellStateStrong): (JSC::JSCell::indexingTypeAndMiscOffset): (JSC::JSCell::indexingTypeOffset): Deleted. * runtime/JSCellInlines.h: (JSC::JSCell::JSCell): (JSC::JSCell::finishCreation): (JSC::JSCell::indexingTypeAndMisc): (JSC::JSCell::indexingType): (JSC::JSCell::setStructure): (JSC::JSCell::callDestructor): (JSC::JSCell::lockInternalLock): (JSC::JSCell::unlockInternalLock): * runtime/JSObject.cpp: (JSC::JSObject::visitButterfly): (JSC::JSObject::visitChildren): (JSC::JSFinalObject::visitChildren): (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists): (JSC::JSObject::createInitialUndecided): (JSC::JSObject::createInitialInt32): (JSC::JSObject::createInitialDouble): (JSC::JSObject::createInitialContiguous): (JSC::JSObject::createArrayStorage): (JSC::JSObject::convertUndecidedToArrayStorage): (JSC::JSObject::convertInt32ToArrayStorage): (JSC::JSObject::convertDoubleToArrayStorage): (JSC::JSObject::convertContiguousToArrayStorage): (JSC::JSObject::deleteProperty): (JSC::JSObject::defineOwnIndexedProperty): (JSC::JSObject::increaseVectorLength): (JSC::JSObject::ensureLengthSlow): (JSC::JSObject::reallocateAndShrinkButterfly): (JSC::JSObject::allocateMoreOutOfLineStorage): (JSC::JSObject::shiftButterflyAfterFlattening): (JSC::JSObject::growOutOfLineStorage): Deleted. * runtime/JSObject.h: (JSC::JSFinalObject::JSFinalObject): (JSC::JSObject::setButterfly): (JSC::JSObject::getOwnNonIndexPropertySlot): (JSC::JSObject::fillCustomGetterPropertySlot): (JSC::JSObject::getOwnPropertySlot): (JSC::JSObject::getPropertySlot): (JSC::JSObject::setStructureAndButterfly): Deleted. (JSC::JSObject::setButterflyWithoutChangingStructure): Deleted. (JSC::JSObject::putDirectInternal): Deleted. (JSC::JSObject::putDirectWithoutTransition): Deleted. * runtime/JSObjectInlines.h: (JSC::JSObject::getPropertySlot): (JSC::JSObject::getNonIndexPropertySlot): (JSC::JSObject::putDirectWithoutTransition): (JSC::JSObject::putDirectInternal): * runtime/Options.h: * runtime/SparseArrayValueMap.h: * runtime/Structure.cpp: (JSC::Structure::dumpStatistics): (JSC::Structure::findStructuresAndMapForMaterialization): (JSC::Structure::materializePropertyTable): (JSC::Structure::addNewPropertyTransition): (JSC::Structure::changePrototypeTransition): (JSC::Structure::attributeChangeTransition): (JSC::Structure::toDictionaryTransition): (JSC::Structure::takePropertyTableOrCloneIfPinned): (JSC::Structure::nonPropertyTransition): (JSC::Structure::isSealed): (JSC::Structure::isFrozen): (JSC::Structure::flattenDictionaryStructure): (JSC::Structure::pin): (JSC::Structure::pinForCaching): (JSC::Structure::willStoreValueSlow): (JSC::Structure::copyPropertyTableForPinning): (JSC::Structure::add): (JSC::Structure::remove): (JSC::Structure::getPropertyNamesFromStructure): (JSC::Structure::visitChildren): (JSC::Structure::materializePropertyMap): Deleted. (JSC::Structure::addPropertyWithoutTransition): Deleted. (JSC::Structure::removePropertyWithoutTransition): Deleted. (JSC::Structure::copyPropertyTable): Deleted. (JSC::Structure::createPropertyMap): Deleted. (JSC::PropertyTable::checkConsistency): Deleted. (JSC::Structure::checkConsistency): Deleted. * runtime/Structure.h: * runtime/StructureIDBlob.h: (JSC::StructureIDBlob::StructureIDBlob): (JSC::StructureIDBlob::indexingTypeIncludingHistory): (JSC::StructureIDBlob::setIndexingTypeIncludingHistory): (JSC::StructureIDBlob::indexingTypeIncludingHistoryOffset): (JSC::StructureIDBlob::indexingType): Deleted. (JSC::StructureIDBlob::setIndexingType): Deleted. (JSC::StructureIDBlob::indexingTypeOffset): Deleted. * runtime/StructureInlines.h: (JSC::Structure::get): (JSC::Structure::checkOffsetConsistency): (JSC::Structure::checkConsistency): (JSC::Structure::add): (JSC::Structure::remove): (JSC::Structure::addPropertyWithoutTransition): (JSC::Structure::removePropertyWithoutTransition): (JSC::Structure::setPropertyTable): (JSC::Structure::putWillGrowOutOfLineStorage): Deleted. (JSC::Structure::propertyTable): Deleted. (JSC::Structure::suggestedNewOutOfLineStorageCapacity): Deleted. Source/WTF: The reason why I went to such great pains to make WTF::Lock fit in two bits is that I knew that I would eventually need to stuff one into some miscellaneous bits of the JSCell header. That time has come, because the concurrent GC has numerous race conditions in visitChildren that can be trivially fixed if each object just has an internal lock. Some cell types might use it to simply protect their entire visitChildren function and anything that mutates the fields it touches, while other cell types might use it as a "lock of last resort" to handle corner cases of an otherwise wait-free or lock-free algorithm. Right now, it's used to protect certain transformations involving indexing storage. To make this happen, I factored the WTF::Lock algorithm into a LockAlgorithm struct that is templatized on lock type (uint8_t for WTF::Lock), the isHeldBit value (1 for WTF::Lock), and the hasParkedBit value (2 for WTF::Lock). This could have been done as a templatized Lock class that basically contains Atomic<LockType>. You could then make any field into a lock by bitwise_casting it to TemplateLock<field type, bit1, bit2>. But this felt too dirty, so instead, LockAlgorithm has static methods that take Atomic<LockType>& as their first argument. I think that this makes it more natural to project a LockAlgorithm onto an existing Atomic<> field. Sadly, some places have to cast their non-Atomic<> field to Atomic<> in order for this to work. Like so many other things we do, this just shows that the C++ style of labeling fields that are subject to atomic ops as atomic is counterproductive. Maybe some day I'll change LockAlgorithm to use our other Atomics API, which does not require Atomic<>. WTF::Lock now uses LockAlgorithm. The slow paths are still outlined. I don't feel too bad about the LockAlgorithm.h header being included in so many places because we change that algorithm so infrequently. Also, I added a hasElapsed(time) function. This function makes it so much more natural to write timeslicing code, which the concurrent GC has to do a lot of. * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ListDump.h: * wtf/Lock.cpp: (WTF::LockBase::lockSlow): (WTF::LockBase::unlockSlow): (WTF::LockBase::unlockFairlySlow): (WTF::LockBase::unlockSlowImpl): Deleted. * wtf/Lock.h: (WTF::LockBase::lock): (WTF::LockBase::tryLock): (WTF::LockBase::unlock): (WTF::LockBase::unlockFairly): (WTF::LockBase::isHeld): (): Deleted. * wtf/LockAlgorithm.h: Added. (WTF::LockAlgorithm::lockFastAssumingZero): (WTF::LockAlgorithm::lockFast): (WTF::LockAlgorithm::lock): (WTF::LockAlgorithm::tryLock): (WTF::LockAlgorithm::unlockFastAssumingZero): (WTF::LockAlgorithm::unlockFast): (WTF::LockAlgorithm::unlock): (WTF::LockAlgorithm::unlockFairly): (WTF::LockAlgorithm::isLocked): (WTF::LockAlgorithm::lockSlow): (WTF::LockAlgorithm::unlockSlow): * wtf/TimeWithDynamicClockType.cpp: (WTF::hasElapsed): * wtf/TimeWithDynamicClockType.h: Canonical link: https://commits.webkit.org/182434@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208720 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-15 01:49:22 +00:00
#include <cmath>
Use pragma once in WTF https://bugs.webkit.org/show_bug.cgi?id=190527 Reviewed by Chris Dumez. Source/WTF: We also need to consistently include wtf headers from within wtf so we can build wtf without symbol redefinition errors from including the copy in Source and the copy in the build directory. * wtf/ASCIICType.h: * wtf/Assertions.cpp: * wtf/Assertions.h: * wtf/Atomics.h: * wtf/AutomaticThread.cpp: * wtf/AutomaticThread.h: * wtf/BackwardsGraph.h: * wtf/Bag.h: * wtf/BagToHashMap.h: * wtf/BitVector.cpp: * wtf/BitVector.h: * wtf/Bitmap.h: * wtf/BloomFilter.h: * wtf/Box.h: * wtf/BubbleSort.h: * wtf/BumpPointerAllocator.h: * wtf/ByteOrder.h: * wtf/CPUTime.cpp: * wtf/CallbackAggregator.h: * wtf/CheckedArithmetic.h: * wtf/CheckedBoolean.h: * wtf/ClockType.cpp: * wtf/ClockType.h: * wtf/CommaPrinter.h: * wtf/CompilationThread.cpp: * wtf/CompilationThread.h: * wtf/Compiler.h: * wtf/ConcurrentPtrHashSet.cpp: * wtf/ConcurrentVector.h: * wtf/Condition.h: * wtf/CountingLock.cpp: * wtf/CrossThreadTaskHandler.cpp: * wtf/CryptographicUtilities.cpp: * wtf/CryptographicUtilities.h: * wtf/CryptographicallyRandomNumber.cpp: * wtf/CryptographicallyRandomNumber.h: * wtf/CurrentTime.cpp: * wtf/DataLog.cpp: * wtf/DataLog.h: * wtf/DateMath.cpp: * wtf/DateMath.h: * wtf/DecimalNumber.cpp: * wtf/DecimalNumber.h: * wtf/Deque.h: * wtf/DisallowCType.h: * wtf/Dominators.h: * wtf/DoublyLinkedList.h: * wtf/FastBitVector.cpp: * wtf/FastMalloc.cpp: * wtf/FastMalloc.h: * wtf/FeatureDefines.h: * wtf/FilePrintStream.cpp: * wtf/FilePrintStream.h: * wtf/FlipBytes.h: * wtf/FunctionDispatcher.cpp: * wtf/FunctionDispatcher.h: * wtf/GetPtr.h: * wtf/Gigacage.cpp: * wtf/GlobalVersion.cpp: * wtf/GraphNodeWorklist.h: * wtf/GregorianDateTime.cpp: * wtf/GregorianDateTime.h: * wtf/HashFunctions.h: * wtf/HashMap.h: * wtf/HashMethod.h: * wtf/HashSet.h: * wtf/HashTable.cpp: * wtf/HashTraits.h: * wtf/Indenter.h: * wtf/IndexSparseSet.h: * wtf/InlineASM.h: * wtf/Insertion.h: * wtf/IteratorAdaptors.h: * wtf/IteratorRange.h: * wtf/JSONValues.cpp: * wtf/JSValueMalloc.cpp: * wtf/LEBDecoder.h: * wtf/Language.cpp: * wtf/ListDump.h: * wtf/Lock.cpp: * wtf/Lock.h: * wtf/LockAlgorithm.h: * wtf/LockedPrintStream.cpp: * wtf/Locker.h: * wtf/MD5.cpp: * wtf/MD5.h: * wtf/MainThread.cpp: * wtf/MainThread.h: * wtf/MallocPtr.h: * wtf/MathExtras.h: * wtf/MediaTime.cpp: * wtf/MediaTime.h: * wtf/MemoryPressureHandler.cpp: * wtf/MessageQueue.h: * wtf/MetaAllocator.cpp: * wtf/MetaAllocator.h: * wtf/MetaAllocatorHandle.h: * wtf/MonotonicTime.cpp: * wtf/MonotonicTime.h: * wtf/NakedPtr.h: * wtf/NoLock.h: * wtf/NoTailCalls.h: * wtf/Noncopyable.h: * wtf/NumberOfCores.cpp: * wtf/NumberOfCores.h: * wtf/OSAllocator.h: * wtf/OSAllocatorPosix.cpp: * wtf/OSRandomSource.cpp: * wtf/OSRandomSource.h: * wtf/ObjcRuntimeExtras.h: * wtf/OrderMaker.h: * wtf/PackedIntVector.h: * wtf/PageAllocation.h: * wtf/PageBlock.cpp: * wtf/PageBlock.h: * wtf/PageReservation.h: * wtf/ParallelHelperPool.cpp: * wtf/ParallelHelperPool.h: * wtf/ParallelJobs.h: * wtf/ParallelJobsLibdispatch.h: * wtf/ParallelVectorIterator.h: * wtf/ParkingLot.cpp: * wtf/ParkingLot.h: * wtf/Platform.h: * wtf/PointerComparison.h: * wtf/Poisoned.cpp: * wtf/PrintStream.cpp: * wtf/PrintStream.h: * wtf/ProcessID.h: * wtf/ProcessPrivilege.cpp: * wtf/RAMSize.cpp: * wtf/RAMSize.h: * wtf/RandomDevice.cpp: * wtf/RandomNumber.cpp: * wtf/RandomNumber.h: * wtf/RandomNumberSeed.h: * wtf/RangeSet.h: * wtf/RawPointer.h: * wtf/ReadWriteLock.cpp: * wtf/RedBlackTree.h: * wtf/Ref.h: * wtf/RefCountedArray.h: * wtf/RefCountedLeakCounter.cpp: * wtf/RefCountedLeakCounter.h: * wtf/RefCounter.h: * wtf/RefPtr.h: * wtf/RetainPtr.h: * wtf/RunLoop.cpp: * wtf/RunLoop.h: * wtf/RunLoopTimer.h: * wtf/RunLoopTimerCF.cpp: * wtf/SHA1.cpp: * wtf/SHA1.h: * wtf/SaturatedArithmetic.h: (saturatedSubtraction): * wtf/SchedulePair.h: * wtf/SchedulePairCF.cpp: * wtf/SchedulePairMac.mm: * wtf/ScopedLambda.h: * wtf/Seconds.cpp: * wtf/Seconds.h: * wtf/SegmentedVector.h: * wtf/SentinelLinkedList.h: * wtf/SharedTask.h: * wtf/SimpleStats.h: * wtf/SingleRootGraph.h: * wtf/SinglyLinkedList.h: * wtf/SixCharacterHash.cpp: * wtf/SixCharacterHash.h: * wtf/SmallPtrSet.h: * wtf/Spectrum.h: * wtf/StackBounds.cpp: * wtf/StackBounds.h: * wtf/StackStats.cpp: * wtf/StackStats.h: * wtf/StackTrace.cpp: * wtf/StdLibExtras.h: * wtf/StreamBuffer.h: * wtf/StringHashDumpContext.h: * wtf/StringPrintStream.cpp: * wtf/StringPrintStream.h: * wtf/ThreadGroup.cpp: * wtf/ThreadMessage.cpp: * wtf/ThreadSpecific.h: * wtf/Threading.cpp: * wtf/Threading.h: * wtf/ThreadingPrimitives.h: * wtf/ThreadingPthreads.cpp: * wtf/TimeWithDynamicClockType.cpp: * wtf/TimeWithDynamicClockType.h: * wtf/TimingScope.cpp: * wtf/TinyLRUCache.h: * wtf/TinyPtrSet.h: * wtf/TriState.h: * wtf/TypeCasts.h: * wtf/UUID.cpp: * wtf/UnionFind.h: * wtf/VMTags.h: * wtf/ValueCheck.h: * wtf/Vector.h: * wtf/VectorTraits.h: * wtf/WallTime.cpp: * wtf/WallTime.h: * wtf/WeakPtr.h: * wtf/WeakRandom.h: * wtf/WordLock.cpp: * wtf/WordLock.h: * wtf/WorkQueue.cpp: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: * wtf/cf/LanguageCF.cpp: * wtf/cf/RunLoopCF.cpp: * wtf/cocoa/Entitlements.mm: * wtf/cocoa/MachSendRight.cpp: * wtf/cocoa/MainThreadCocoa.mm: * wtf/cocoa/MemoryFootprintCocoa.cpp: * wtf/cocoa/WorkQueueCocoa.cpp: * wtf/dtoa.cpp: * wtf/dtoa.h: * wtf/ios/WebCoreThread.cpp: * wtf/ios/WebCoreThread.h: * wtf/mac/AppKitCompatibilityDeclarations.h: * wtf/mac/DeprecatedSymbolsUsedBySafari.mm: * wtf/mbmalloc.cpp: * wtf/persistence/PersistentCoders.cpp: * wtf/persistence/PersistentDecoder.cpp: * wtf/persistence/PersistentEncoder.cpp: * wtf/spi/cf/CFBundleSPI.h: * wtf/spi/darwin/CommonCryptoSPI.h: * wtf/text/ASCIIFastPath.h: * wtf/text/ASCIILiteral.cpp: * wtf/text/AtomicString.cpp: * wtf/text/AtomicString.h: * wtf/text/AtomicStringHash.h: * wtf/text/AtomicStringImpl.cpp: * wtf/text/AtomicStringImpl.h: * wtf/text/AtomicStringTable.cpp: * wtf/text/AtomicStringTable.h: * wtf/text/Base64.cpp: * wtf/text/CString.cpp: * wtf/text/CString.h: * wtf/text/ConversionMode.h: * wtf/text/ExternalStringImpl.cpp: * wtf/text/IntegerToStringConversion.h: * wtf/text/LChar.h: * wtf/text/LineEnding.cpp: * wtf/text/StringBuffer.h: * wtf/text/StringBuilder.cpp: * wtf/text/StringBuilder.h: * wtf/text/StringBuilderJSON.cpp: * wtf/text/StringCommon.h: * wtf/text/StringConcatenate.h: * wtf/text/StringHash.h: * wtf/text/StringImpl.cpp: * wtf/text/StringImpl.h: * wtf/text/StringOperators.h: * wtf/text/StringView.cpp: * wtf/text/StringView.h: * wtf/text/SymbolImpl.cpp: * wtf/text/SymbolRegistry.cpp: * wtf/text/SymbolRegistry.h: * wtf/text/TextBreakIterator.cpp: * wtf/text/TextBreakIterator.h: * wtf/text/TextBreakIteratorInternalICU.h: * wtf/text/TextPosition.h: * wtf/text/TextStream.cpp: * wtf/text/UniquedStringImpl.h: * wtf/text/WTFString.cpp: * wtf/text/WTFString.h: * wtf/text/cocoa/StringCocoa.mm: * wtf/text/cocoa/StringViewCocoa.mm: * wtf/text/cocoa/TextBreakIteratorInternalICUCocoa.cpp: * wtf/text/icu/UTextProvider.cpp: * wtf/text/icu/UTextProvider.h: * wtf/text/icu/UTextProviderLatin1.cpp: * wtf/text/icu/UTextProviderLatin1.h: * wtf/text/icu/UTextProviderUTF16.cpp: * wtf/text/icu/UTextProviderUTF16.h: * wtf/threads/BinarySemaphore.cpp: * wtf/threads/BinarySemaphore.h: * wtf/threads/Signals.cpp: * wtf/unicode/CharacterNames.h: * wtf/unicode/Collator.h: * wtf/unicode/CollatorDefault.cpp: * wtf/unicode/UTF8.cpp: * wtf/unicode/UTF8.h: Tools: Put WorkQueue in namespace DRT so it does not conflict with WTF::WorkQueue. * DumpRenderTree/TestRunner.cpp: (TestRunner::queueLoadHTMLString): (TestRunner::queueLoadAlternateHTMLString): (TestRunner::queueBackNavigation): (TestRunner::queueForwardNavigation): (TestRunner::queueLoadingScript): (TestRunner::queueNonLoadingScript): (TestRunner::queueReload): * DumpRenderTree/WorkQueue.cpp: (WorkQueue::singleton): Deleted. (WorkQueue::WorkQueue): Deleted. (WorkQueue::queue): Deleted. (WorkQueue::dequeue): Deleted. (WorkQueue::count): Deleted. (WorkQueue::clear): Deleted. (WorkQueue::processWork): Deleted. * DumpRenderTree/WorkQueue.h: (WorkQueue::setFrozen): Deleted. * DumpRenderTree/WorkQueueItem.h: * DumpRenderTree/mac/DumpRenderTree.mm: (runTest): * DumpRenderTree/mac/FrameLoadDelegate.mm: (-[FrameLoadDelegate processWork:]): (-[FrameLoadDelegate webView:locationChangeDone:forDataSource:]): * DumpRenderTree/mac/TestRunnerMac.mm: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): * DumpRenderTree/win/DumpRenderTree.cpp: (runTest): * DumpRenderTree/win/FrameLoadDelegate.cpp: (FrameLoadDelegate::processWork): (FrameLoadDelegate::locationChangeDone): * DumpRenderTree/win/TestRunnerWin.cpp: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): Canonical link: https://commits.webkit.org/205473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237099 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-15 14:24:49 +00:00
#include <wtf/Condition.h>
#include <wtf/PrintStream.h>
#include <wtf/Lock.h>
WTF::ParkingLot should stop using std::chrono because std::chrono::duration casts are prone to overflows https://bugs.webkit.org/show_bug.cgi?id=152045 Reviewed by Andy Estes. Source/JavaScriptCore: Probably the nicest example of why this patch is a good idea is the change in AtomicsObject.cpp. * jit/ICStats.cpp: (JSC::ICStats::ICStats): * runtime/AtomicsObject.cpp: (JSC::atomicsFuncWait): Source/WebCore: No new layout tests because no new behavior. The new WTF time classes have some unit tests in TestWebKitAPI. * fileapi/ThreadableBlobRegistry.cpp: (WebCore::ThreadableBlobRegistry::blobSize): * platform/MainThreadSharedTimer.h: * platform/SharedTimer.h: * platform/ThreadTimers.cpp: (WebCore::ThreadTimers::updateSharedTimer): * platform/cf/MainThreadSharedTimerCF.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/efl/MainThreadSharedTimerEfl.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/glib/MainThreadSharedTimerGLib.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/win/MainThreadSharedTimerWin.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * workers/WorkerRunLoop.cpp: (WebCore::WorkerRunLoop::runInMode): Source/WebKit2: * Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageState::wait): (IPC::Connection::sendMessage): (IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting): (IPC::Connection::waitForMessage): (IPC::Connection::sendSyncMessage): (IPC::Connection::waitForSyncReply): * Platform/IPC/Connection.h: (IPC::Connection::sendSync): (IPC::Connection::waitForAndDispatchImmediately): * Platform/IPC/MessageSender.h: (IPC::MessageSender::sendSync): * UIProcess/ChildProcessProxy.h: (WebKit::ChildProcessProxy::sendSync): * UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): * UIProcess/Storage/StorageManager.cpp: (WebKit::StorageManager::applicationWillTerminate): * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::sendProcessWillSuspendImminently): * UIProcess/WebResourceLoadStatisticsStore.cpp: (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate): * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (-[WKOneShotDisplayLinkHandler displayLinkFired:]): (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay): (WebKit::RemoteLayerTreeDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/WKImmediateActionController.mm: (-[WKImmediateActionController immediateActionRecognizerWillBeginAnimation:]): * UIProcess/mac/WebPageProxyMac.mm: (WebKit::WebPageProxy::stringSelectionForPasteboard): (WebKit::WebPageProxy::dataSelectionForPasteboard): (WebKit::WebPageProxy::readSelectionFromPasteboard): (WebKit::WebPageProxy::shouldDelayWindowOrderingForEvent): (WebKit::WebPageProxy::acceptsFirstMouse): * WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): (WebKit::WebChromeClient::runJavaScriptAlert): (WebKit::WebChromeClient::runJavaScriptConfirm): (WebKit::WebChromeClient::runJavaScriptPrompt): (WebKit::WebChromeClient::print): (WebKit::WebChromeClient::exceededDatabaseQuota): (WebKit::WebChromeClient::reachedApplicationCacheOriginQuota): * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::postSynchronousMessageForTesting): Source/WTF: We used to use 'double' for all time measurements. Sometimes it was milliseconds, sometimes it was seconds. Sometimes we measured a span of time, sometimes we spoke of time since some epoch. When we spoke of time since epoch, we either used a monotonic clock or a wall clock. The type - always 'double' - never told us what kind of time we had, even though there were roughly six of them (sec interval, ms interval, sec since epoch on wall, ms since epoch on wall, sec since epoch monotonic, ms since epoch monotonic). At some point, we thought that it would be a good idea to replace these doubles with std::chrono. But since replacing some things with std::chrono, we found it to be terribly inconvenient: - Outrageous API. I never want to say std::chrono::milliseconds(blah). I never want to say std::chrono::steady_clock::timepoint. The syntax for duration_cast is ugly, and ideally duration_cast would not even be a thing. - No overflow protection. std::chrono uses integers by default and using anything else is clumsy. But the integer math is done without regard for the rough edges of integer math, so any cast between std::chrono types risks overflow. Any comparison risks overflow because it may do conversions silently. We have even found bugs where some C++ implementations had more overflows than others, which ends up being a special kind of hell. In many cases, the overflow also has nasal demons. It's an error to represent time using integers. It would have been excusable back when floating point math was not guaranteed to be supported on all platforms, but that would have been a long time ago. Time is a continuous, infinite concept and it's a perfect fit for floating point: - Floating point preserves precision under multiplication in all but extreme cases, so using floating point for time means that unit conversions are almost completely lossless. This means that we don't have to think very hard about what units to use. In this patch, we use seconds almost everywhere. We only convert at boundaries, like an API boundary that wants something other than seconds. - Floating point makes it easy to reason about infinity, which is something that time code wants to do a lot. Example: when would you like to timeout? Infinity please! This is the most elegant way of having an API support both a timeout variant and a no-timeout variant. - Floating point does well-understood things when math goes wrong, and these things are pretty well optimized to match what a mathematician would do when computing with real numbers represented using scientific notation with a finite number of significant digits. This means that time math under floating point looks like normal math. On the other hand, std::chrono time math looks like garbage because you have to always check for multiple possible UB corners whenever you touch large integers. Integers that represent time are very likely to be large and you don't have to do much to overflow them. At this time, based on the number of bugs we have already seen due to chrono overflows, I am not certain that we even understand what are all of the corner cases that we should even check for. This patch introduces a new set of timekeeping classes that are all based on double, and all internally use seconds. These classes support algebraic typing. The classes are: - Seconds: this is for measuring a duration. - WallTime: time since epoch according to a wall clock (aka real time clock). - MonotonicTime: time since epoch according to a monotonic clock. - ClockType: enum that says either Wall or Monotonic. - TimeWithDynamicClockType: a tuple of double and ClockType, which represents either a wall time or a monotonic time. All of these classes behave like C++ values and are cheap to copy around since they are very nearly POD. This supports comprehensive conversions between the various time types. Most of this is by way of algebra. Here are just some of the rules we recognize: WallTime = WallTime + Seconds Seconds = WallTime - WallTime MonotonicTime = MonotonicTime + Seconds etc... We support negative, infinite, and NaN times because math. We support conversions between MonotonicTime and WallTime, like: WallTime wt = mt.approximateWallTime() This is called this "approximate" because the only way to do it is to get the current time on both clocks and convert relative to that. Many of our APIs would be happy using whatever notion of time the user wanted to use. For those APIs, which includes Condition and ParkingLot, we have TimeWithDynamicClockType. You can automatically convert WallTime or MonotonicTime to TimeWithDynamicClockType. This means that if you use a WallTime with Condition::waitUntil, then Condition's internal logic for when it should wake up makes its decision based on the current WallTime - but if you use MonotonicTime then waitUntil will make its decision based on current MonotonicTime. This is a greater level of flexibility than chrono allowed, since chrono did not have the concept of a dynamic clock type. This patch does not include conversions between std::chrono and these new time classes, because past experience shows that we're quite bad at getting conversions between std::chrono and anything else right. Also, I didn't need such conversion code because this patch only converts code that transitively touches ParkingLot and Condition. It was easy to get all of that code onto the new time classes. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::start): * wtf/CMakeLists.txt: * wtf/ClockType.cpp: Added. (WTF::printInternal): * wtf/ClockType.h: Added. * wtf/Condition.h: (WTF::ConditionBase::waitUntil): (WTF::ConditionBase::waitFor): (WTF::ConditionBase::wait): (WTF::ConditionBase::waitUntilWallClockSeconds): Deleted. (WTF::ConditionBase::waitUntilMonotonicClockSeconds): Deleted. (WTF::ConditionBase::waitForSeconds): Deleted. (WTF::ConditionBase::waitForSecondsImpl): Deleted. (WTF::ConditionBase::waitForImpl): Deleted. (WTF::ConditionBase::absoluteFromRelative): Deleted. * wtf/CrossThreadQueue.h: (WTF::CrossThreadQueue<DataType>::waitForMessage): * wtf/CurrentTime.cpp: (WTF::sleep): * wtf/MessageQueue.h: (WTF::MessageQueue::infiniteTime): Deleted. * wtf/MonotonicTime.cpp: Added. (WTF::MonotonicTime::now): (WTF::MonotonicTime::approximateWallTime): (WTF::MonotonicTime::dump): (WTF::MonotonicTime::sleep): * wtf/MonotonicTime.h: Added. (WTF::MonotonicTime::MonotonicTime): (WTF::MonotonicTime::fromRawDouble): (WTF::MonotonicTime::infinity): (WTF::MonotonicTime::secondsSinceEpoch): (WTF::MonotonicTime::approximateMonotonicTime): (WTF::MonotonicTime::operator bool): (WTF::MonotonicTime::operator+): (WTF::MonotonicTime::operator-): (WTF::MonotonicTime::operator+=): (WTF::MonotonicTime::operator-=): (WTF::MonotonicTime::operator==): (WTF::MonotonicTime::operator!=): (WTF::MonotonicTime::operator<): (WTF::MonotonicTime::operator>): (WTF::MonotonicTime::operator<=): (WTF::MonotonicTime::operator>=): * wtf/ParkingLot.cpp: (WTF::ParkingLot::parkConditionallyImpl): (WTF::ParkingLot::unparkOne): (WTF::ParkingLot::unparkOneImpl): (WTF::ParkingLot::unparkCount): * wtf/ParkingLot.h: (WTF::ParkingLot::parkConditionally): (WTF::ParkingLot::compareAndPark): * wtf/Seconds.cpp: Added. (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::dump): (WTF::Seconds::sleep): * wtf/Seconds.h: Added. (WTF::Seconds::Seconds): (WTF::Seconds::value): (WTF::Seconds::seconds): (WTF::Seconds::milliseconds): (WTF::Seconds::microseconds): (WTF::Seconds::nanoseconds): (WTF::Seconds::fromMilliseconds): (WTF::Seconds::fromMicroseconds): (WTF::Seconds::fromNanoseconds): (WTF::Seconds::infinity): (WTF::Seconds::operator bool): (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::operator*): (WTF::Seconds::operator/): (WTF::Seconds::operator+=): (WTF::Seconds::operator-=): (WTF::Seconds::operator*=): (WTF::Seconds::operator/=): (WTF::Seconds::operator==): (WTF::Seconds::operator!=): (WTF::Seconds::operator<): (WTF::Seconds::operator>): (WTF::Seconds::operator<=): (WTF::Seconds::operator>=): * wtf/TimeWithDynamicClockType.cpp: Added. (WTF::TimeWithDynamicClockType::now): (WTF::TimeWithDynamicClockType::nowWithSameClock): (WTF::TimeWithDynamicClockType::wallTime): (WTF::TimeWithDynamicClockType::monotonicTime): (WTF::TimeWithDynamicClockType::approximateWallTime): (WTF::TimeWithDynamicClockType::approximateMonotonicTime): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator<): (WTF::TimeWithDynamicClockType::operator>): (WTF::TimeWithDynamicClockType::operator<=): (WTF::TimeWithDynamicClockType::operator>=): (WTF::TimeWithDynamicClockType::dump): (WTF::TimeWithDynamicClockType::sleep): * wtf/TimeWithDynamicClockType.h: Added. (WTF::TimeWithDynamicClockType::TimeWithDynamicClockType): (WTF::TimeWithDynamicClockType::fromRawDouble): (WTF::TimeWithDynamicClockType::secondsSinceEpoch): (WTF::TimeWithDynamicClockType::clockType): (WTF::TimeWithDynamicClockType::withSameClockAndRawDouble): (WTF::TimeWithDynamicClockType::operator bool): (WTF::TimeWithDynamicClockType::operator+): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator+=): (WTF::TimeWithDynamicClockType::operator-=): (WTF::TimeWithDynamicClockType::operator==): (WTF::TimeWithDynamicClockType::operator!=): * wtf/WallTime.cpp: Added. (WTF::WallTime::now): (WTF::WallTime::approximateMonotonicTime): (WTF::WallTime::dump): (WTF::WallTime::sleep): * wtf/WallTime.h: Added. (WTF::WallTime::WallTime): (WTF::WallTime::fromRawDouble): (WTF::WallTime::infinity): (WTF::WallTime::secondsSinceEpoch): (WTF::WallTime::approximateWallTime): (WTF::WallTime::operator bool): (WTF::WallTime::operator+): (WTF::WallTime::operator-): (WTF::WallTime::operator+=): (WTF::WallTime::operator-=): (WTF::WallTime::operator==): (WTF::WallTime::operator!=): (WTF::WallTime::operator<): (WTF::WallTime::operator>): (WTF::WallTime::operator<=): (WTF::WallTime::operator>=): * wtf/threads/BinarySemaphore.cpp: (WTF::BinarySemaphore::wait): * wtf/threads/BinarySemaphore.h: Tools: * TestWebKitAPI/CMakeLists.txt: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WTF/Condition.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: (TestWebKitAPI::ToUpperConverter::stopProducing): (TestWebKitAPI::ToUpperConverter::stopConsuming): * TestWebKitAPI/Tests/WTF/Time.cpp: Added. (WTF::operator<<): (TestWebKitAPI::TEST): Canonical link: https://commits.webkit.org/182152@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-05 03:02:39 +00:00
namespace WTF {
TimeWithDynamicClockType TimeWithDynamicClockType::now(ClockType type)
{
switch (type) {
case ClockType::Wall:
return WallTime::now();
case ClockType::Monotonic:
return MonotonicTime::now();
}
RELEASE_ASSERT_NOT_REACHED();
return TimeWithDynamicClockType();
}
TimeWithDynamicClockType TimeWithDynamicClockType::nowWithSameClock() const
{
return now(clockType());
}
WallTime TimeWithDynamicClockType::wallTime() const
{
RELEASE_ASSERT(m_type == ClockType::Wall);
return WallTime::fromRawSeconds(m_value);
}
MonotonicTime TimeWithDynamicClockType::monotonicTime() const
{
RELEASE_ASSERT(m_type == ClockType::Monotonic);
return MonotonicTime::fromRawSeconds(m_value);
}
WallTime TimeWithDynamicClockType::approximateWallTime() const
{
switch (m_type) {
case ClockType::Wall:
return wallTime();
case ClockType::Monotonic:
return monotonicTime().approximateWallTime();
}
RELEASE_ASSERT_NOT_REACHED();
return WallTime();
}
MonotonicTime TimeWithDynamicClockType::approximateMonotonicTime() const
{
switch (m_type) {
case ClockType::Wall:
return wallTime().approximateMonotonicTime();
case ClockType::Monotonic:
return monotonicTime();
}
RELEASE_ASSERT_NOT_REACHED();
return MonotonicTime();
}
Seconds TimeWithDynamicClockType::operator-(const TimeWithDynamicClockType& other) const
{
RELEASE_ASSERT(m_type == other.m_type);
return Seconds(m_value - other.m_value);
}
bool TimeWithDynamicClockType::operator<(const TimeWithDynamicClockType& other) const
{
RELEASE_ASSERT(m_type == other.m_type);
return m_value < other.m_value;
}
bool TimeWithDynamicClockType::operator>(const TimeWithDynamicClockType& other) const
{
RELEASE_ASSERT(m_type == other.m_type);
return m_value > other.m_value;
}
bool TimeWithDynamicClockType::operator<=(const TimeWithDynamicClockType& other) const
{
RELEASE_ASSERT(m_type == other.m_type);
return m_value <= other.m_value;
}
bool TimeWithDynamicClockType::operator>=(const TimeWithDynamicClockType& other) const
{
RELEASE_ASSERT(m_type == other.m_type);
return m_value >= other.m_value;
}
void TimeWithDynamicClockType::dump(PrintStream& out) const
{
out.print(m_type, "(", m_value, " sec)");
}
void sleep(const TimeWithDynamicClockType& time)
{
Lock fakeLock;
Condition fakeCondition;
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker fakeLocker { fakeLock };
WTF::ParkingLot should stop using std::chrono because std::chrono::duration casts are prone to overflows https://bugs.webkit.org/show_bug.cgi?id=152045 Reviewed by Andy Estes. Source/JavaScriptCore: Probably the nicest example of why this patch is a good idea is the change in AtomicsObject.cpp. * jit/ICStats.cpp: (JSC::ICStats::ICStats): * runtime/AtomicsObject.cpp: (JSC::atomicsFuncWait): Source/WebCore: No new layout tests because no new behavior. The new WTF time classes have some unit tests in TestWebKitAPI. * fileapi/ThreadableBlobRegistry.cpp: (WebCore::ThreadableBlobRegistry::blobSize): * platform/MainThreadSharedTimer.h: * platform/SharedTimer.h: * platform/ThreadTimers.cpp: (WebCore::ThreadTimers::updateSharedTimer): * platform/cf/MainThreadSharedTimerCF.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/efl/MainThreadSharedTimerEfl.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/glib/MainThreadSharedTimerGLib.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/win/MainThreadSharedTimerWin.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * workers/WorkerRunLoop.cpp: (WebCore::WorkerRunLoop::runInMode): Source/WebKit2: * Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageState::wait): (IPC::Connection::sendMessage): (IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting): (IPC::Connection::waitForMessage): (IPC::Connection::sendSyncMessage): (IPC::Connection::waitForSyncReply): * Platform/IPC/Connection.h: (IPC::Connection::sendSync): (IPC::Connection::waitForAndDispatchImmediately): * Platform/IPC/MessageSender.h: (IPC::MessageSender::sendSync): * UIProcess/ChildProcessProxy.h: (WebKit::ChildProcessProxy::sendSync): * UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): * UIProcess/Storage/StorageManager.cpp: (WebKit::StorageManager::applicationWillTerminate): * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::sendProcessWillSuspendImminently): * UIProcess/WebResourceLoadStatisticsStore.cpp: (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate): * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (-[WKOneShotDisplayLinkHandler displayLinkFired:]): (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay): (WebKit::RemoteLayerTreeDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/WKImmediateActionController.mm: (-[WKImmediateActionController immediateActionRecognizerWillBeginAnimation:]): * UIProcess/mac/WebPageProxyMac.mm: (WebKit::WebPageProxy::stringSelectionForPasteboard): (WebKit::WebPageProxy::dataSelectionForPasteboard): (WebKit::WebPageProxy::readSelectionFromPasteboard): (WebKit::WebPageProxy::shouldDelayWindowOrderingForEvent): (WebKit::WebPageProxy::acceptsFirstMouse): * WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): (WebKit::WebChromeClient::runJavaScriptAlert): (WebKit::WebChromeClient::runJavaScriptConfirm): (WebKit::WebChromeClient::runJavaScriptPrompt): (WebKit::WebChromeClient::print): (WebKit::WebChromeClient::exceededDatabaseQuota): (WebKit::WebChromeClient::reachedApplicationCacheOriginQuota): * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::postSynchronousMessageForTesting): Source/WTF: We used to use 'double' for all time measurements. Sometimes it was milliseconds, sometimes it was seconds. Sometimes we measured a span of time, sometimes we spoke of time since some epoch. When we spoke of time since epoch, we either used a monotonic clock or a wall clock. The type - always 'double' - never told us what kind of time we had, even though there were roughly six of them (sec interval, ms interval, sec since epoch on wall, ms since epoch on wall, sec since epoch monotonic, ms since epoch monotonic). At some point, we thought that it would be a good idea to replace these doubles with std::chrono. But since replacing some things with std::chrono, we found it to be terribly inconvenient: - Outrageous API. I never want to say std::chrono::milliseconds(blah). I never want to say std::chrono::steady_clock::timepoint. The syntax for duration_cast is ugly, and ideally duration_cast would not even be a thing. - No overflow protection. std::chrono uses integers by default and using anything else is clumsy. But the integer math is done without regard for the rough edges of integer math, so any cast between std::chrono types risks overflow. Any comparison risks overflow because it may do conversions silently. We have even found bugs where some C++ implementations had more overflows than others, which ends up being a special kind of hell. In many cases, the overflow also has nasal demons. It's an error to represent time using integers. It would have been excusable back when floating point math was not guaranteed to be supported on all platforms, but that would have been a long time ago. Time is a continuous, infinite concept and it's a perfect fit for floating point: - Floating point preserves precision under multiplication in all but extreme cases, so using floating point for time means that unit conversions are almost completely lossless. This means that we don't have to think very hard about what units to use. In this patch, we use seconds almost everywhere. We only convert at boundaries, like an API boundary that wants something other than seconds. - Floating point makes it easy to reason about infinity, which is something that time code wants to do a lot. Example: when would you like to timeout? Infinity please! This is the most elegant way of having an API support both a timeout variant and a no-timeout variant. - Floating point does well-understood things when math goes wrong, and these things are pretty well optimized to match what a mathematician would do when computing with real numbers represented using scientific notation with a finite number of significant digits. This means that time math under floating point looks like normal math. On the other hand, std::chrono time math looks like garbage because you have to always check for multiple possible UB corners whenever you touch large integers. Integers that represent time are very likely to be large and you don't have to do much to overflow them. At this time, based on the number of bugs we have already seen due to chrono overflows, I am not certain that we even understand what are all of the corner cases that we should even check for. This patch introduces a new set of timekeeping classes that are all based on double, and all internally use seconds. These classes support algebraic typing. The classes are: - Seconds: this is for measuring a duration. - WallTime: time since epoch according to a wall clock (aka real time clock). - MonotonicTime: time since epoch according to a monotonic clock. - ClockType: enum that says either Wall or Monotonic. - TimeWithDynamicClockType: a tuple of double and ClockType, which represents either a wall time or a monotonic time. All of these classes behave like C++ values and are cheap to copy around since they are very nearly POD. This supports comprehensive conversions between the various time types. Most of this is by way of algebra. Here are just some of the rules we recognize: WallTime = WallTime + Seconds Seconds = WallTime - WallTime MonotonicTime = MonotonicTime + Seconds etc... We support negative, infinite, and NaN times because math. We support conversions between MonotonicTime and WallTime, like: WallTime wt = mt.approximateWallTime() This is called this "approximate" because the only way to do it is to get the current time on both clocks and convert relative to that. Many of our APIs would be happy using whatever notion of time the user wanted to use. For those APIs, which includes Condition and ParkingLot, we have TimeWithDynamicClockType. You can automatically convert WallTime or MonotonicTime to TimeWithDynamicClockType. This means that if you use a WallTime with Condition::waitUntil, then Condition's internal logic for when it should wake up makes its decision based on the current WallTime - but if you use MonotonicTime then waitUntil will make its decision based on current MonotonicTime. This is a greater level of flexibility than chrono allowed, since chrono did not have the concept of a dynamic clock type. This patch does not include conversions between std::chrono and these new time classes, because past experience shows that we're quite bad at getting conversions between std::chrono and anything else right. Also, I didn't need such conversion code because this patch only converts code that transitively touches ParkingLot and Condition. It was easy to get all of that code onto the new time classes. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::start): * wtf/CMakeLists.txt: * wtf/ClockType.cpp: Added. (WTF::printInternal): * wtf/ClockType.h: Added. * wtf/Condition.h: (WTF::ConditionBase::waitUntil): (WTF::ConditionBase::waitFor): (WTF::ConditionBase::wait): (WTF::ConditionBase::waitUntilWallClockSeconds): Deleted. (WTF::ConditionBase::waitUntilMonotonicClockSeconds): Deleted. (WTF::ConditionBase::waitForSeconds): Deleted. (WTF::ConditionBase::waitForSecondsImpl): Deleted. (WTF::ConditionBase::waitForImpl): Deleted. (WTF::ConditionBase::absoluteFromRelative): Deleted. * wtf/CrossThreadQueue.h: (WTF::CrossThreadQueue<DataType>::waitForMessage): * wtf/CurrentTime.cpp: (WTF::sleep): * wtf/MessageQueue.h: (WTF::MessageQueue::infiniteTime): Deleted. * wtf/MonotonicTime.cpp: Added. (WTF::MonotonicTime::now): (WTF::MonotonicTime::approximateWallTime): (WTF::MonotonicTime::dump): (WTF::MonotonicTime::sleep): * wtf/MonotonicTime.h: Added. (WTF::MonotonicTime::MonotonicTime): (WTF::MonotonicTime::fromRawDouble): (WTF::MonotonicTime::infinity): (WTF::MonotonicTime::secondsSinceEpoch): (WTF::MonotonicTime::approximateMonotonicTime): (WTF::MonotonicTime::operator bool): (WTF::MonotonicTime::operator+): (WTF::MonotonicTime::operator-): (WTF::MonotonicTime::operator+=): (WTF::MonotonicTime::operator-=): (WTF::MonotonicTime::operator==): (WTF::MonotonicTime::operator!=): (WTF::MonotonicTime::operator<): (WTF::MonotonicTime::operator>): (WTF::MonotonicTime::operator<=): (WTF::MonotonicTime::operator>=): * wtf/ParkingLot.cpp: (WTF::ParkingLot::parkConditionallyImpl): (WTF::ParkingLot::unparkOne): (WTF::ParkingLot::unparkOneImpl): (WTF::ParkingLot::unparkCount): * wtf/ParkingLot.h: (WTF::ParkingLot::parkConditionally): (WTF::ParkingLot::compareAndPark): * wtf/Seconds.cpp: Added. (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::dump): (WTF::Seconds::sleep): * wtf/Seconds.h: Added. (WTF::Seconds::Seconds): (WTF::Seconds::value): (WTF::Seconds::seconds): (WTF::Seconds::milliseconds): (WTF::Seconds::microseconds): (WTF::Seconds::nanoseconds): (WTF::Seconds::fromMilliseconds): (WTF::Seconds::fromMicroseconds): (WTF::Seconds::fromNanoseconds): (WTF::Seconds::infinity): (WTF::Seconds::operator bool): (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::operator*): (WTF::Seconds::operator/): (WTF::Seconds::operator+=): (WTF::Seconds::operator-=): (WTF::Seconds::operator*=): (WTF::Seconds::operator/=): (WTF::Seconds::operator==): (WTF::Seconds::operator!=): (WTF::Seconds::operator<): (WTF::Seconds::operator>): (WTF::Seconds::operator<=): (WTF::Seconds::operator>=): * wtf/TimeWithDynamicClockType.cpp: Added. (WTF::TimeWithDynamicClockType::now): (WTF::TimeWithDynamicClockType::nowWithSameClock): (WTF::TimeWithDynamicClockType::wallTime): (WTF::TimeWithDynamicClockType::monotonicTime): (WTF::TimeWithDynamicClockType::approximateWallTime): (WTF::TimeWithDynamicClockType::approximateMonotonicTime): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator<): (WTF::TimeWithDynamicClockType::operator>): (WTF::TimeWithDynamicClockType::operator<=): (WTF::TimeWithDynamicClockType::operator>=): (WTF::TimeWithDynamicClockType::dump): (WTF::TimeWithDynamicClockType::sleep): * wtf/TimeWithDynamicClockType.h: Added. (WTF::TimeWithDynamicClockType::TimeWithDynamicClockType): (WTF::TimeWithDynamicClockType::fromRawDouble): (WTF::TimeWithDynamicClockType::secondsSinceEpoch): (WTF::TimeWithDynamicClockType::clockType): (WTF::TimeWithDynamicClockType::withSameClockAndRawDouble): (WTF::TimeWithDynamicClockType::operator bool): (WTF::TimeWithDynamicClockType::operator+): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator+=): (WTF::TimeWithDynamicClockType::operator-=): (WTF::TimeWithDynamicClockType::operator==): (WTF::TimeWithDynamicClockType::operator!=): * wtf/WallTime.cpp: Added. (WTF::WallTime::now): (WTF::WallTime::approximateMonotonicTime): (WTF::WallTime::dump): (WTF::WallTime::sleep): * wtf/WallTime.h: Added. (WTF::WallTime::WallTime): (WTF::WallTime::fromRawDouble): (WTF::WallTime::infinity): (WTF::WallTime::secondsSinceEpoch): (WTF::WallTime::approximateWallTime): (WTF::WallTime::operator bool): (WTF::WallTime::operator+): (WTF::WallTime::operator-): (WTF::WallTime::operator+=): (WTF::WallTime::operator-=): (WTF::WallTime::operator==): (WTF::WallTime::operator!=): (WTF::WallTime::operator<): (WTF::WallTime::operator>): (WTF::WallTime::operator<=): (WTF::WallTime::operator>=): * wtf/threads/BinarySemaphore.cpp: (WTF::BinarySemaphore::wait): * wtf/threads/BinarySemaphore.h: Tools: * TestWebKitAPI/CMakeLists.txt: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WTF/Condition.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: (TestWebKitAPI::ToUpperConverter::stopProducing): (TestWebKitAPI::ToUpperConverter::stopConsuming): * TestWebKitAPI/Tests/WTF/Time.cpp: Added. (WTF::operator<<): (TestWebKitAPI::TEST): Canonical link: https://commits.webkit.org/182152@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-05 03:02:39 +00:00
fakeCondition.waitUntil(fakeLock, time);
}
The GC should be optionally concurrent and disabled by default https://bugs.webkit.org/show_bug.cgi?id=164454 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This started out as a patch to have the GC scan the stack at the end, and then the outage happened and I decided to pick a more aggresive target: give the GC a concurrent mode that can be enabled at runtime, and whose only effect is that it turns on the ResumeTheWorldScope. This gives our GC a really intuitive workflow: by default, the GC thread is running solo with the world stopped and the parallel markers converged and waiting. We have a parallel work scope to enable the parallel markers and now we have a ResumeTheWorldScope that will optionally resume the world and then stop it again. It's easy to make a concurrent GC that always instantly crashes. I can't promise that this one won't do that when you run it. I set a specific goal: I wanted to do >10 concurrent GCs in debug mode with generations, optimizing JITs, and parallel marking disabled. To reach this milestone, I needed to do a bunch of stuff: - The mutator needs a separate mark stack for the barrier, since it will mutate this stack concurrently to the collector's slot visitors. - The use of CellState to indicate whether an object is being scanned the first time or a subsequent time was racy. It fails spectacularly when a barrier is fired at the same time as visitChildren is running or if the barrier runs at the same time as the GC marks the same object. So, I split SlotVisitor's mark stacks. It's now the case that you know why you're being scanned by looking at which stack you came off of. - All of root marking must be in the collector fixpoint. I renamed markRoots to markToFixpoint. They say concurrency is hard, but the collector looks more intuitive this way. We never gained anything from forcing people to make a choice between scanning something in the fixpoint versus outside of it. Because root scanning is cheap, we can afford to do it repeatedly, which means all root scanning can now do constraint-based marking (like: I'll mark you if that thing is marked). - JSObject::visitChildren's scanning of the butterfly raced with property additions, indexed storage transitions and resizing, and a bunch of miscellaneous dirty butterfly reshaping functions - like the one that flattens a dictionary and some sneaky ArrayStorage transformations. Many of these can be fixed by using store-store fences in the mutator and load-load fences in the collector. I've adopted the rule that the collector must always see either a butterfly and structure that match or a newer butterfly with an older structure, where their age is just one transition apart. This can be achieved with fences. For the cases where it breaks down, I added a lock to every JSCell. This is a full-fledged WTF lock that we sneak into two available bits in the indexingType. See the WTF ChangeLog for details. The mutator fencing rules are as follows: - Store-store fence before and after setting the butterfly. - Store-store fence before setting structure if you had changed the shape of the butterfly. - Store-store fence after initializing all fields in an allocation. - A dictionary Structure can change in strange ways while the GC is trying to scan it. So, JSObject::visitChildren will now grab the object's structure's lock if the object's structure is a dictionary. Dictionary structures are 1:1 with their object, so this does not reduce GC parallelism (super unlikely that the GC will simultaneously scan an object from two threads). - The GC can blow away a Structure's property table at any time. As a small consolation, it's now holding the Structure's lock when it does so. But there was tons of code in Structure that uses DeferGC to prevent the GC from blowing away the property table. This doesn't work with concurrent GC, since DeferGC only means that the GC won't run its safepoint (i.e. stop-the-world code) in the DeferGC region. It will still do marking and it was the Structure::visitChildren that would delete the table. It turns out that Structure's reliance on the property table not being deleted was the product of code rot. We already had functions that would materialize the table on demand. We were simply making the mistake of saying: structure->materializePropertyMap(); ... structure->propertyTable()->things Instead of saying: PropertyTable* table = structure->ensurePropertyTable(); ... table->things Switching the code to use the latter idiom allowed me to simplify the code a lot while fixing the race. - The LLInt's get_by_val handling was broken because the indexing shape constants were wrong. Once I started putting more things into the IndexingType, that started causing crashes for me. So I fixed LLInt. That turned out to be a lot of work, since that code had rotted in subtle ways. This is a speed-up in SunSpider, probably because of the LLInt fix. This is neutral on Octane and Kraken. It's a smaller slow-down on LongSpider, but I think we can ignore that (we don't view LongSpider as an official benchmark). By default, the concurrent GC is disabled: in all of the places where it would have resumed the world to run marking concurrently to the mutator, it will just skip the resume step. When you enable concurrent GC (--useConcurrentGC=true), it can sometimes run Octane/splay to completion. It seems to perform quite well: on my machine, it improves both splay-throughput and splay-latency. It's probably unstable for other programs. * API/JSVirtualMachine.mm: (-[JSVirtualMachine isOldExternalObject:]): * assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::storeFence): * bytecode/InlineAccess.cpp: (JSC::InlineAccess::dumpCacheSizesAndCrash): (JSC::InlineAccess::generateSelfPropertyAccess): (JSC::InlineAccess::generateArrayLength): * bytecode/ObjectAllocationProfile.h: (JSC::ObjectAllocationProfile::offsetOfInlineCapacity): (JSC::ObjectAllocationProfile::ObjectAllocationProfile): (JSC::ObjectAllocationProfile::initialize): (JSC::ObjectAllocationProfile::inlineCapacity): (JSC::ObjectAllocationProfile::clear): * bytecode/PolymorphicAccess.cpp: (JSC::AccessCase::generateWithGuard): (JSC::AccessCase::generateImpl): * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGOSRExitCompiler32_64.cpp: (JSC::DFG::OSRExitCompiler::compileExit): * dfg/DFGOSRExitCompiler64.cpp: (JSC::DFG::OSRExitCompiler::compileExit): * dfg/DFGOperations.cpp: * dfg/DFGPlan.cpp: (JSC::DFG::Plan::markCodeBlocks): (JSC::DFG::Plan::rememberCodeBlocks): * dfg/DFGPlan.h: * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::emitAllocateRawObject): (JSC::DFG::SpeculativeJIT::checkArray): (JSC::DFG::SpeculativeJIT::arrayify): (JSC::DFG::SpeculativeJIT::compileMakeRope): (JSC::DFG::SpeculativeJIT::compileNewFunctionCommon): (JSC::DFG::SpeculativeJIT::compileCreateActivation): (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments): (JSC::DFG::SpeculativeJIT::compileSpread): (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): (JSC::DFG::SpeculativeJIT::compileNewStringObject): (JSC::DFG::SpeculativeJIT::compileNewTypedArray): (JSC::DFG::SpeculativeJIT::compileStoreBarrier): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): * dfg/DFGTierUpCheckInjectionPhase.cpp: (JSC::DFG::TierUpCheckInjectionPhase::run): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::markCodeBlocks): (JSC::DFG::Worklist::rememberCodeBlocks): (JSC::DFG::markCodeBlocks): (JSC::DFG::completeAllPlansForVM): (JSC::DFG::rememberCodeBlocks): * dfg/DFGWorklist.h: * ftl/FTLAbstractHeapRepository.cpp: (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository): (JSC::FTL::AbstractHeapRepository::computeRangesAndDecorateInstructions): * ftl/FTLAbstractHeapRepository.h: * ftl/FTLJITCode.cpp: (JSC::FTL::JITCode::~JITCode): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compilePutStructure): (JSC::FTL::DFG::LowerDFGToB3::compileCreateActivation): (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction): (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments): (JSC::FTL::DFG::LowerDFGToB3::compileCreateRest): (JSC::FTL::DFG::LowerDFGToB3::compileNewObject): (JSC::FTL::DFG::LowerDFGToB3::compileNewArray): (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread): (JSC::FTL::DFG::LowerDFGToB3::compileSpread): (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayBuffer): (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize): (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): (JSC::FTL::DFG::LowerDFGToB3::compileMakeRope): (JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset): (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeCreateActivation): (JSC::FTL::DFG::LowerDFGToB3::splatWords): (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorage): (JSC::FTL::DFG::LowerDFGToB3::reallocatePropertyStorage): (JSC::FTL::DFG::LowerDFGToB3::allocateObject): (JSC::FTL::DFG::LowerDFGToB3::isArrayType): (JSC::FTL::DFG::LowerDFGToB3::emitStoreBarrier): (JSC::FTL::DFG::LowerDFGToB3::mutatorFence): (JSC::FTL::DFG::LowerDFGToB3::setButterfly): * ftl/FTLOSRExitCompiler.cpp: (JSC::FTL::compileStub): * ftl/FTLOutput.cpp: (JSC::FTL::Output::signExt32ToPtr): (JSC::FTL::Output::fence): * ftl/FTLOutput.h: * heap/CellState.h: * heap/GCSegmentedArray.h: * heap/Heap.cpp: (JSC::Heap::ResumeTheWorldScope::ResumeTheWorldScope): (JSC::Heap::ResumeTheWorldScope::~ResumeTheWorldScope): (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::harvestWeakReferences): (JSC::Heap::finalizeUnconditionalFinalizers): (JSC::Heap::completeAllJITPlans): (JSC::Heap::markToFixpoint): (JSC::Heap::gatherStackRoots): (JSC::Heap::beginMarking): (JSC::Heap::visitConservativeRoots): (JSC::Heap::visitCompilerWorklistWeakReferences): (JSC::Heap::updateObjectCounts): (JSC::Heap::endMarking): (JSC::Heap::addToRememberedSet): (JSC::Heap::collectInThread): (JSC::Heap::stopTheWorld): (JSC::Heap::resumeTheWorld): (JSC::Heap::setGCDidJIT): (JSC::Heap::setNeedFinalize): (JSC::Heap::setMutatorWaiting): (JSC::Heap::clearMutatorWaiting): (JSC::Heap::finalize): (JSC::Heap::flushWriteBarrierBuffer): (JSC::Heap::writeBarrierSlowPath): (JSC::Heap::canCollect): (JSC::Heap::reportExtraMemoryVisited): (JSC::Heap::reportExternalMemoryVisited): (JSC::Heap::notifyIsSafeToCollect): (JSC::Heap::markRoots): Deleted. (JSC::Heap::visitExternalRememberedSet): Deleted. (JSC::Heap::visitSmallStrings): Deleted. (JSC::Heap::visitProtectedObjects): Deleted. (JSC::Heap::visitArgumentBuffers): Deleted. (JSC::Heap::visitException): Deleted. (JSC::Heap::visitStrongHandles): Deleted. (JSC::Heap::visitHandleStack): Deleted. (JSC::Heap::visitSamplingProfiler): Deleted. (JSC::Heap::visitTypeProfiler): Deleted. (JSC::Heap::visitShadowChicken): Deleted. (JSC::Heap::traceCodeBlocksAndJITStubRoutines): Deleted. (JSC::Heap::visitWeakHandles): Deleted. (JSC::Heap::flushOldStructureIDTables): Deleted. (JSC::Heap::stopAllocation): Deleted. * heap/Heap.h: (JSC::Heap::collectorSlotVisitor): (JSC::Heap::mutatorMarkStack): (JSC::Heap::mutatorShouldBeFenced): (JSC::Heap::addressOfMutatorShouldBeFenced): (JSC::Heap::slotVisitor): Deleted. (JSC::Heap::notifyIsSafeToCollect): Deleted. (JSC::Heap::barrierShouldBeFenced): Deleted. (JSC::Heap::addressOfBarrierShouldBeFenced): Deleted. * heap/MarkStack.cpp: (JSC::MarkStackArray::transferTo): * heap/MarkStack.h: * heap/MarkedAllocator.cpp: (JSC::MarkedAllocator::tryAllocateIn): * heap/MarkedBlock.cpp: (JSC::MarkedBlock::MarkedBlock): (JSC::MarkedBlock::Handle::specializedSweep): (JSC::MarkedBlock::Handle::sweep): (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): (JSC::MarkedBlock::Handle::stopAllocating): (JSC::MarkedBlock::Handle::resumeAllocating): (JSC::MarkedBlock::aboutToMarkSlow): (JSC::MarkedBlock::Handle::didConsumeFreeList): (JSC::SetNewlyAllocatedFunctor::SetNewlyAllocatedFunctor): Deleted. (JSC::SetNewlyAllocatedFunctor::operator()): Deleted. * heap/MarkedBlock.h: * heap/MarkedSpace.cpp: (JSC::MarkedSpace::resumeAllocating): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::SlotVisitor): (JSC::SlotVisitor::~SlotVisitor): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::clearMarkStacks): (JSC::SlotVisitor::appendJSCellOrAuxiliary): (JSC::SlotVisitor::setMarkedAndAppendToMarkStack): (JSC::SlotVisitor::appendToMarkStack): (JSC::SlotVisitor::appendToMutatorMarkStack): (JSC::SlotVisitor::visitChildren): (JSC::SlotVisitor::donateKnownParallel): (JSC::SlotVisitor::drain): (JSC::SlotVisitor::drainFromShared): (JSC::SlotVisitor::containsOpaqueRoot): (JSC::SlotVisitor::donateAndDrain): (JSC::SlotVisitor::mergeOpaqueRoots): (JSC::SlotVisitor::dump): (JSC::SlotVisitor::clearMarkStack): Deleted. (JSC::SlotVisitor::opaqueRootCount): Deleted. * heap/SlotVisitor.h: (JSC::SlotVisitor::collectorMarkStack): (JSC::SlotVisitor::mutatorMarkStack): (JSC::SlotVisitor::isEmpty): (JSC::SlotVisitor::bytesVisited): (JSC::SlotVisitor::markStack): Deleted. (JSC::SlotVisitor::bytesCopied): Deleted. * heap/SlotVisitorInlines.h: (JSC::SlotVisitor::reportExtraMemoryVisited): (JSC::SlotVisitor::reportExternalMemoryVisited): * jit/AssemblyHelpers.cpp: (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): * jit/AssemblyHelpers.h: (JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo): (JSC::AssemblyHelpers::barrierStoreLoadFence): (JSC::AssemblyHelpers::mutatorFence): (JSC::AssemblyHelpers::storeButterfly): (JSC::AssemblyHelpers::jumpIfMutatorFenceNotNeeded): (JSC::AssemblyHelpers::emitInitializeInlineStorage): (JSC::AssemblyHelpers::emitInitializeOutOfLineStorage): (JSC::AssemblyHelpers::jumpIfBarrierStoreLoadFenceNotNeeded): Deleted. * jit/JITInlines.h: (JSC::JIT::emitArrayProfilingSiteWithCell): * jit/JITOperations.cpp: * jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_put_to_scope): (JSC::JIT::emit_op_put_to_arguments): * llint/LLIntData.cpp: (JSC::LLInt::Data::performAssertions): * llint/LowLevelInterpreter.asm: * llint/LowLevelInterpreter64.asm: * runtime/ButterflyInlines.h: (JSC::Butterfly::create): (JSC::Butterfly::createOrGrowPropertyStorage): * runtime/ConcurrentJITLock.h: (JSC::GCSafeConcurrentJITLocker::NoDefer::NoDefer): Deleted. * runtime/GenericArgumentsInlines.h: (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex): (JSC::GenericArguments<Type>::putByIndex): * runtime/IndexingType.h: * runtime/JSArray.cpp: (JSC::JSArray::unshiftCountSlowCase): (JSC::JSArray::unshiftCountWithArrayStorage): * runtime/JSCell.h: (JSC::JSCell::InternalLocker::InternalLocker): (JSC::JSCell::InternalLocker::~InternalLocker): (JSC::JSCell::atomicCompareExchangeCellStateWeakRelaxed): (JSC::JSCell::atomicCompareExchangeCellStateStrong): (JSC::JSCell::indexingTypeAndMiscOffset): (JSC::JSCell::indexingTypeOffset): Deleted. * runtime/JSCellInlines.h: (JSC::JSCell::JSCell): (JSC::JSCell::finishCreation): (JSC::JSCell::indexingTypeAndMisc): (JSC::JSCell::indexingType): (JSC::JSCell::setStructure): (JSC::JSCell::callDestructor): (JSC::JSCell::lockInternalLock): (JSC::JSCell::unlockInternalLock): * runtime/JSObject.cpp: (JSC::JSObject::visitButterfly): (JSC::JSObject::visitChildren): (JSC::JSFinalObject::visitChildren): (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists): (JSC::JSObject::createInitialUndecided): (JSC::JSObject::createInitialInt32): (JSC::JSObject::createInitialDouble): (JSC::JSObject::createInitialContiguous): (JSC::JSObject::createArrayStorage): (JSC::JSObject::convertUndecidedToArrayStorage): (JSC::JSObject::convertInt32ToArrayStorage): (JSC::JSObject::convertDoubleToArrayStorage): (JSC::JSObject::convertContiguousToArrayStorage): (JSC::JSObject::deleteProperty): (JSC::JSObject::defineOwnIndexedProperty): (JSC::JSObject::increaseVectorLength): (JSC::JSObject::ensureLengthSlow): (JSC::JSObject::reallocateAndShrinkButterfly): (JSC::JSObject::allocateMoreOutOfLineStorage): (JSC::JSObject::shiftButterflyAfterFlattening): (JSC::JSObject::growOutOfLineStorage): Deleted. * runtime/JSObject.h: (JSC::JSFinalObject::JSFinalObject): (JSC::JSObject::setButterfly): (JSC::JSObject::getOwnNonIndexPropertySlot): (JSC::JSObject::fillCustomGetterPropertySlot): (JSC::JSObject::getOwnPropertySlot): (JSC::JSObject::getPropertySlot): (JSC::JSObject::setStructureAndButterfly): Deleted. (JSC::JSObject::setButterflyWithoutChangingStructure): Deleted. (JSC::JSObject::putDirectInternal): Deleted. (JSC::JSObject::putDirectWithoutTransition): Deleted. * runtime/JSObjectInlines.h: (JSC::JSObject::getPropertySlot): (JSC::JSObject::getNonIndexPropertySlot): (JSC::JSObject::putDirectWithoutTransition): (JSC::JSObject::putDirectInternal): * runtime/Options.h: * runtime/SparseArrayValueMap.h: * runtime/Structure.cpp: (JSC::Structure::dumpStatistics): (JSC::Structure::findStructuresAndMapForMaterialization): (JSC::Structure::materializePropertyTable): (JSC::Structure::addNewPropertyTransition): (JSC::Structure::changePrototypeTransition): (JSC::Structure::attributeChangeTransition): (JSC::Structure::toDictionaryTransition): (JSC::Structure::takePropertyTableOrCloneIfPinned): (JSC::Structure::nonPropertyTransition): (JSC::Structure::isSealed): (JSC::Structure::isFrozen): (JSC::Structure::flattenDictionaryStructure): (JSC::Structure::pin): (JSC::Structure::pinForCaching): (JSC::Structure::willStoreValueSlow): (JSC::Structure::copyPropertyTableForPinning): (JSC::Structure::add): (JSC::Structure::remove): (JSC::Structure::getPropertyNamesFromStructure): (JSC::Structure::visitChildren): (JSC::Structure::materializePropertyMap): Deleted. (JSC::Structure::addPropertyWithoutTransition): Deleted. (JSC::Structure::removePropertyWithoutTransition): Deleted. (JSC::Structure::copyPropertyTable): Deleted. (JSC::Structure::createPropertyMap): Deleted. (JSC::PropertyTable::checkConsistency): Deleted. (JSC::Structure::checkConsistency): Deleted. * runtime/Structure.h: * runtime/StructureIDBlob.h: (JSC::StructureIDBlob::StructureIDBlob): (JSC::StructureIDBlob::indexingTypeIncludingHistory): (JSC::StructureIDBlob::setIndexingTypeIncludingHistory): (JSC::StructureIDBlob::indexingTypeIncludingHistoryOffset): (JSC::StructureIDBlob::indexingType): Deleted. (JSC::StructureIDBlob::setIndexingType): Deleted. (JSC::StructureIDBlob::indexingTypeOffset): Deleted. * runtime/StructureInlines.h: (JSC::Structure::get): (JSC::Structure::checkOffsetConsistency): (JSC::Structure::checkConsistency): (JSC::Structure::add): (JSC::Structure::remove): (JSC::Structure::addPropertyWithoutTransition): (JSC::Structure::removePropertyWithoutTransition): (JSC::Structure::setPropertyTable): (JSC::Structure::putWillGrowOutOfLineStorage): Deleted. (JSC::Structure::propertyTable): Deleted. (JSC::Structure::suggestedNewOutOfLineStorageCapacity): Deleted. Source/WTF: The reason why I went to such great pains to make WTF::Lock fit in two bits is that I knew that I would eventually need to stuff one into some miscellaneous bits of the JSCell header. That time has come, because the concurrent GC has numerous race conditions in visitChildren that can be trivially fixed if each object just has an internal lock. Some cell types might use it to simply protect their entire visitChildren function and anything that mutates the fields it touches, while other cell types might use it as a "lock of last resort" to handle corner cases of an otherwise wait-free or lock-free algorithm. Right now, it's used to protect certain transformations involving indexing storage. To make this happen, I factored the WTF::Lock algorithm into a LockAlgorithm struct that is templatized on lock type (uint8_t for WTF::Lock), the isHeldBit value (1 for WTF::Lock), and the hasParkedBit value (2 for WTF::Lock). This could have been done as a templatized Lock class that basically contains Atomic<LockType>. You could then make any field into a lock by bitwise_casting it to TemplateLock<field type, bit1, bit2>. But this felt too dirty, so instead, LockAlgorithm has static methods that take Atomic<LockType>& as their first argument. I think that this makes it more natural to project a LockAlgorithm onto an existing Atomic<> field. Sadly, some places have to cast their non-Atomic<> field to Atomic<> in order for this to work. Like so many other things we do, this just shows that the C++ style of labeling fields that are subject to atomic ops as atomic is counterproductive. Maybe some day I'll change LockAlgorithm to use our other Atomics API, which does not require Atomic<>. WTF::Lock now uses LockAlgorithm. The slow paths are still outlined. I don't feel too bad about the LockAlgorithm.h header being included in so many places because we change that algorithm so infrequently. Also, I added a hasElapsed(time) function. This function makes it so much more natural to write timeslicing code, which the concurrent GC has to do a lot of. * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ListDump.h: * wtf/Lock.cpp: (WTF::LockBase::lockSlow): (WTF::LockBase::unlockSlow): (WTF::LockBase::unlockFairlySlow): (WTF::LockBase::unlockSlowImpl): Deleted. * wtf/Lock.h: (WTF::LockBase::lock): (WTF::LockBase::tryLock): (WTF::LockBase::unlock): (WTF::LockBase::unlockFairly): (WTF::LockBase::isHeld): (): Deleted. * wtf/LockAlgorithm.h: Added. (WTF::LockAlgorithm::lockFastAssumingZero): (WTF::LockAlgorithm::lockFast): (WTF::LockAlgorithm::lock): (WTF::LockAlgorithm::tryLock): (WTF::LockAlgorithm::unlockFastAssumingZero): (WTF::LockAlgorithm::unlockFast): (WTF::LockAlgorithm::unlock): (WTF::LockAlgorithm::unlockFairly): (WTF::LockAlgorithm::isLocked): (WTF::LockAlgorithm::lockSlow): (WTF::LockAlgorithm::unlockSlow): * wtf/TimeWithDynamicClockType.cpp: (WTF::hasElapsed): * wtf/TimeWithDynamicClockType.h: Canonical link: https://commits.webkit.org/182434@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208720 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-15 01:49:22 +00:00
bool hasElapsed(const TimeWithDynamicClockType& time)
{
// Avoid doing now().
if (!(time > time.withSameClockAndRawSeconds(0)))
return true;
if (std::isinf(time.secondsSinceEpoch().value()))
return false;
return time <= time.nowWithSameClock();
}
WTF::ParkingLot should stop using std::chrono because std::chrono::duration casts are prone to overflows https://bugs.webkit.org/show_bug.cgi?id=152045 Reviewed by Andy Estes. Source/JavaScriptCore: Probably the nicest example of why this patch is a good idea is the change in AtomicsObject.cpp. * jit/ICStats.cpp: (JSC::ICStats::ICStats): * runtime/AtomicsObject.cpp: (JSC::atomicsFuncWait): Source/WebCore: No new layout tests because no new behavior. The new WTF time classes have some unit tests in TestWebKitAPI. * fileapi/ThreadableBlobRegistry.cpp: (WebCore::ThreadableBlobRegistry::blobSize): * platform/MainThreadSharedTimer.h: * platform/SharedTimer.h: * platform/ThreadTimers.cpp: (WebCore::ThreadTimers::updateSharedTimer): * platform/cf/MainThreadSharedTimerCF.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/efl/MainThreadSharedTimerEfl.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/glib/MainThreadSharedTimerGLib.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * platform/win/MainThreadSharedTimerWin.cpp: (WebCore::MainThreadSharedTimer::setFireInterval): * workers/WorkerRunLoop.cpp: (WebCore::WorkerRunLoop::runInMode): Source/WebKit2: * Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageState::wait): (IPC::Connection::sendMessage): (IPC::Connection::timeoutRespectingIgnoreTimeoutsForTesting): (IPC::Connection::waitForMessage): (IPC::Connection::sendSyncMessage): (IPC::Connection::waitForSyncReply): * Platform/IPC/Connection.h: (IPC::Connection::sendSync): (IPC::Connection::waitForAndDispatchImmediately): * Platform/IPC/MessageSender.h: (IPC::MessageSender::sendSync): * UIProcess/ChildProcessProxy.h: (WebKit::ChildProcessProxy::sendSync): * UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::sendProcessWillSuspendImminently): * UIProcess/Storage/StorageManager.cpp: (WebKit::StorageManager::applicationWillTerminate): * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::sendProcessWillSuspendImminently): * UIProcess/WebResourceLoadStatisticsStore.cpp: (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate): * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (-[WKOneShotDisplayLinkHandler displayLinkFired:]): (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay): (WebKit::RemoteLayerTreeDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::waitForDidUpdateActivityState): * UIProcess/mac/WKImmediateActionController.mm: (-[WKImmediateActionController immediateActionRecognizerWillBeginAnimation:]): * UIProcess/mac/WebPageProxyMac.mm: (WebKit::WebPageProxy::stringSelectionForPasteboard): (WebKit::WebPageProxy::dataSelectionForPasteboard): (WebKit::WebPageProxy::readSelectionFromPasteboard): (WebKit::WebPageProxy::shouldDelayWindowOrderingForEvent): (WebKit::WebPageProxy::acceptsFirstMouse): * WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): (WebKit::WebChromeClient::runJavaScriptAlert): (WebKit::WebChromeClient::runJavaScriptConfirm): (WebKit::WebChromeClient::runJavaScriptPrompt): (WebKit::WebChromeClient::print): (WebKit::WebChromeClient::exceededDatabaseQuota): (WebKit::WebChromeClient::reachedApplicationCacheOriginQuota): * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::postSynchronousMessageForTesting): Source/WTF: We used to use 'double' for all time measurements. Sometimes it was milliseconds, sometimes it was seconds. Sometimes we measured a span of time, sometimes we spoke of time since some epoch. When we spoke of time since epoch, we either used a monotonic clock or a wall clock. The type - always 'double' - never told us what kind of time we had, even though there were roughly six of them (sec interval, ms interval, sec since epoch on wall, ms since epoch on wall, sec since epoch monotonic, ms since epoch monotonic). At some point, we thought that it would be a good idea to replace these doubles with std::chrono. But since replacing some things with std::chrono, we found it to be terribly inconvenient: - Outrageous API. I never want to say std::chrono::milliseconds(blah). I never want to say std::chrono::steady_clock::timepoint. The syntax for duration_cast is ugly, and ideally duration_cast would not even be a thing. - No overflow protection. std::chrono uses integers by default and using anything else is clumsy. But the integer math is done without regard for the rough edges of integer math, so any cast between std::chrono types risks overflow. Any comparison risks overflow because it may do conversions silently. We have even found bugs where some C++ implementations had more overflows than others, which ends up being a special kind of hell. In many cases, the overflow also has nasal demons. It's an error to represent time using integers. It would have been excusable back when floating point math was not guaranteed to be supported on all platforms, but that would have been a long time ago. Time is a continuous, infinite concept and it's a perfect fit for floating point: - Floating point preserves precision under multiplication in all but extreme cases, so using floating point for time means that unit conversions are almost completely lossless. This means that we don't have to think very hard about what units to use. In this patch, we use seconds almost everywhere. We only convert at boundaries, like an API boundary that wants something other than seconds. - Floating point makes it easy to reason about infinity, which is something that time code wants to do a lot. Example: when would you like to timeout? Infinity please! This is the most elegant way of having an API support both a timeout variant and a no-timeout variant. - Floating point does well-understood things when math goes wrong, and these things are pretty well optimized to match what a mathematician would do when computing with real numbers represented using scientific notation with a finite number of significant digits. This means that time math under floating point looks like normal math. On the other hand, std::chrono time math looks like garbage because you have to always check for multiple possible UB corners whenever you touch large integers. Integers that represent time are very likely to be large and you don't have to do much to overflow them. At this time, based on the number of bugs we have already seen due to chrono overflows, I am not certain that we even understand what are all of the corner cases that we should even check for. This patch introduces a new set of timekeeping classes that are all based on double, and all internally use seconds. These classes support algebraic typing. The classes are: - Seconds: this is for measuring a duration. - WallTime: time since epoch according to a wall clock (aka real time clock). - MonotonicTime: time since epoch according to a monotonic clock. - ClockType: enum that says either Wall or Monotonic. - TimeWithDynamicClockType: a tuple of double and ClockType, which represents either a wall time or a monotonic time. All of these classes behave like C++ values and are cheap to copy around since they are very nearly POD. This supports comprehensive conversions between the various time types. Most of this is by way of algebra. Here are just some of the rules we recognize: WallTime = WallTime + Seconds Seconds = WallTime - WallTime MonotonicTime = MonotonicTime + Seconds etc... We support negative, infinite, and NaN times because math. We support conversions between MonotonicTime and WallTime, like: WallTime wt = mt.approximateWallTime() This is called this "approximate" because the only way to do it is to get the current time on both clocks and convert relative to that. Many of our APIs would be happy using whatever notion of time the user wanted to use. For those APIs, which includes Condition and ParkingLot, we have TimeWithDynamicClockType. You can automatically convert WallTime or MonotonicTime to TimeWithDynamicClockType. This means that if you use a WallTime with Condition::waitUntil, then Condition's internal logic for when it should wake up makes its decision based on the current WallTime - but if you use MonotonicTime then waitUntil will make its decision based on current MonotonicTime. This is a greater level of flexibility than chrono allowed, since chrono did not have the concept of a dynamic clock type. This patch does not include conversions between std::chrono and these new time classes, because past experience shows that we're quite bad at getting conversions between std::chrono and anything else right. Also, I didn't need such conversion code because this patch only converts code that transitively touches ParkingLot and Condition. It was easy to get all of that code onto the new time classes. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::start): * wtf/CMakeLists.txt: * wtf/ClockType.cpp: Added. (WTF::printInternal): * wtf/ClockType.h: Added. * wtf/Condition.h: (WTF::ConditionBase::waitUntil): (WTF::ConditionBase::waitFor): (WTF::ConditionBase::wait): (WTF::ConditionBase::waitUntilWallClockSeconds): Deleted. (WTF::ConditionBase::waitUntilMonotonicClockSeconds): Deleted. (WTF::ConditionBase::waitForSeconds): Deleted. (WTF::ConditionBase::waitForSecondsImpl): Deleted. (WTF::ConditionBase::waitForImpl): Deleted. (WTF::ConditionBase::absoluteFromRelative): Deleted. * wtf/CrossThreadQueue.h: (WTF::CrossThreadQueue<DataType>::waitForMessage): * wtf/CurrentTime.cpp: (WTF::sleep): * wtf/MessageQueue.h: (WTF::MessageQueue::infiniteTime): Deleted. * wtf/MonotonicTime.cpp: Added. (WTF::MonotonicTime::now): (WTF::MonotonicTime::approximateWallTime): (WTF::MonotonicTime::dump): (WTF::MonotonicTime::sleep): * wtf/MonotonicTime.h: Added. (WTF::MonotonicTime::MonotonicTime): (WTF::MonotonicTime::fromRawDouble): (WTF::MonotonicTime::infinity): (WTF::MonotonicTime::secondsSinceEpoch): (WTF::MonotonicTime::approximateMonotonicTime): (WTF::MonotonicTime::operator bool): (WTF::MonotonicTime::operator+): (WTF::MonotonicTime::operator-): (WTF::MonotonicTime::operator+=): (WTF::MonotonicTime::operator-=): (WTF::MonotonicTime::operator==): (WTF::MonotonicTime::operator!=): (WTF::MonotonicTime::operator<): (WTF::MonotonicTime::operator>): (WTF::MonotonicTime::operator<=): (WTF::MonotonicTime::operator>=): * wtf/ParkingLot.cpp: (WTF::ParkingLot::parkConditionallyImpl): (WTF::ParkingLot::unparkOne): (WTF::ParkingLot::unparkOneImpl): (WTF::ParkingLot::unparkCount): * wtf/ParkingLot.h: (WTF::ParkingLot::parkConditionally): (WTF::ParkingLot::compareAndPark): * wtf/Seconds.cpp: Added. (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::dump): (WTF::Seconds::sleep): * wtf/Seconds.h: Added. (WTF::Seconds::Seconds): (WTF::Seconds::value): (WTF::Seconds::seconds): (WTF::Seconds::milliseconds): (WTF::Seconds::microseconds): (WTF::Seconds::nanoseconds): (WTF::Seconds::fromMilliseconds): (WTF::Seconds::fromMicroseconds): (WTF::Seconds::fromNanoseconds): (WTF::Seconds::infinity): (WTF::Seconds::operator bool): (WTF::Seconds::operator+): (WTF::Seconds::operator-): (WTF::Seconds::operator*): (WTF::Seconds::operator/): (WTF::Seconds::operator+=): (WTF::Seconds::operator-=): (WTF::Seconds::operator*=): (WTF::Seconds::operator/=): (WTF::Seconds::operator==): (WTF::Seconds::operator!=): (WTF::Seconds::operator<): (WTF::Seconds::operator>): (WTF::Seconds::operator<=): (WTF::Seconds::operator>=): * wtf/TimeWithDynamicClockType.cpp: Added. (WTF::TimeWithDynamicClockType::now): (WTF::TimeWithDynamicClockType::nowWithSameClock): (WTF::TimeWithDynamicClockType::wallTime): (WTF::TimeWithDynamicClockType::monotonicTime): (WTF::TimeWithDynamicClockType::approximateWallTime): (WTF::TimeWithDynamicClockType::approximateMonotonicTime): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator<): (WTF::TimeWithDynamicClockType::operator>): (WTF::TimeWithDynamicClockType::operator<=): (WTF::TimeWithDynamicClockType::operator>=): (WTF::TimeWithDynamicClockType::dump): (WTF::TimeWithDynamicClockType::sleep): * wtf/TimeWithDynamicClockType.h: Added. (WTF::TimeWithDynamicClockType::TimeWithDynamicClockType): (WTF::TimeWithDynamicClockType::fromRawDouble): (WTF::TimeWithDynamicClockType::secondsSinceEpoch): (WTF::TimeWithDynamicClockType::clockType): (WTF::TimeWithDynamicClockType::withSameClockAndRawDouble): (WTF::TimeWithDynamicClockType::operator bool): (WTF::TimeWithDynamicClockType::operator+): (WTF::TimeWithDynamicClockType::operator-): (WTF::TimeWithDynamicClockType::operator+=): (WTF::TimeWithDynamicClockType::operator-=): (WTF::TimeWithDynamicClockType::operator==): (WTF::TimeWithDynamicClockType::operator!=): * wtf/WallTime.cpp: Added. (WTF::WallTime::now): (WTF::WallTime::approximateMonotonicTime): (WTF::WallTime::dump): (WTF::WallTime::sleep): * wtf/WallTime.h: Added. (WTF::WallTime::WallTime): (WTF::WallTime::fromRawDouble): (WTF::WallTime::infinity): (WTF::WallTime::secondsSinceEpoch): (WTF::WallTime::approximateWallTime): (WTF::WallTime::operator bool): (WTF::WallTime::operator+): (WTF::WallTime::operator-): (WTF::WallTime::operator+=): (WTF::WallTime::operator-=): (WTF::WallTime::operator==): (WTF::WallTime::operator!=): (WTF::WallTime::operator<): (WTF::WallTime::operator>): (WTF::WallTime::operator<=): (WTF::WallTime::operator>=): * wtf/threads/BinarySemaphore.cpp: (WTF::BinarySemaphore::wait): * wtf/threads/BinarySemaphore.h: Tools: * TestWebKitAPI/CMakeLists.txt: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WTF/Condition.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/SynchronizedFixedQueue.cpp: (TestWebKitAPI::ToUpperConverter::stopProducing): (TestWebKitAPI::ToUpperConverter::stopConsuming): * TestWebKitAPI/Tests/WTF/Time.cpp: Added. (WTF::operator<<): (TestWebKitAPI::TEST): Canonical link: https://commits.webkit.org/182152@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-05 03:02:39 +00:00
} // namespace WTF