Add a LazyNeverDestroyed class template and use it
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 1 Jun 2014 22:31:13 +0000 (22:31 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 1 Jun 2014 22:31:13 +0000 (22:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133425

Reviewed by Darin Adler.

Source/JavaScriptCore:
* dfg/DFGFunctionWhitelist.cpp:
(JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
* dfg/DFGFunctionWhitelist.h:

Source/WebCore:
* Modules/webdatabase/DatabaseBackendBase.cpp:
(WebCore::guidMutex):
* crypto/CryptoAlgorithmRegistry.cpp:
(WebCore::registryMutex):
* inspector/WorkerDebuggerAgent.cpp:
* loader/CrossOriginAccessControl.cpp:
(WebCore::isOnAccessControlResponseHeaderWhitelist):
* platform/network/NetworkStateNotifier.cpp:
(WebCore::networkStateNotifier):
* workers/DefaultSharedWorkerRepository.cpp:
(WebCore::DefaultSharedWorkerRepository::instance):
* workers/DefaultSharedWorkerRepository.h:
* workers/WorkerThread.cpp:
(WebCore::threadSetMutex):
* xml/XMLHttpRequest.cpp:
(WebCore::staticData):

Source/WebKit2:
* Shared/mac/SecItemShim.cpp:
(WebKit::responseMap):

Source/WTF:
LazyNeverDestroyed is similar to NeverDestroyed, except it's lazily constructed
by calling construct(). This makes it useful for using inside std::call_once functions.

* wtf/Forward.h:
* wtf/NeverDestroyed.h:
(WTF::LazyNeverDestroyed::construct):
(WTF::LazyNeverDestroyed::operator T&):
(WTF::LazyNeverDestroyed::get):
(WTF::LazyNeverDestroyed::asPtr):
(WTF::LazyNeverDestroyed::MaybeRelax::MaybeRelax):
* wtf/mac/DeprecatedSymbolsUsedBySafari.mm:
(WTF::atomicallyInitializedStaticMutex):
* wtf/unicode/icu/CollatorICU.cpp:
(WTF::cachedCollatorMutex):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@169518 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGFunctionWhitelist.cpp
Source/JavaScriptCore/dfg/DFGFunctionWhitelist.h
Source/WTF/ChangeLog
Source/WTF/wtf/Forward.h
Source/WTF/wtf/NeverDestroyed.h
Source/WTF/wtf/mac/DeprecatedSymbolsUsedBySafari.mm
Source/WTF/wtf/unicode/icu/CollatorICU.cpp
Source/WebCore/ChangeLog
Source/WebCore/Modules/webdatabase/DatabaseBackendBase.cpp
Source/WebCore/crypto/CryptoAlgorithmRegistry.cpp
Source/WebCore/inspector/WorkerDebuggerAgent.cpp
Source/WebCore/loader/CrossOriginAccessControl.cpp
Source/WebCore/platform/network/NetworkStateNotifier.cpp
Source/WebCore/workers/DefaultSharedWorkerRepository.cpp
Source/WebCore/workers/DefaultSharedWorkerRepository.h
Source/WebCore/workers/WorkerThread.cpp
Source/WebCore/xml/XMLHttpRequest.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/SecItemShim.cpp

index ec314dd..80ff83b 100644 (file)
@@ -1,3 +1,14 @@
+2014-05-31  Anders Carlsson  <andersca@apple.com>
+
+        Add a LazyNeverDestroyed class template and use it
+        https://bugs.webkit.org/show_bug.cgi?id=133425
+
+        Reviewed by Darin Adler.
+
+        * dfg/DFGFunctionWhitelist.cpp:
+        (JSC::DFG::FunctionWhitelist::ensureGlobalWhitelist):
+        * dfg/DFGFunctionWhitelist.h:
+
 2014-05-28  Filip Pizlo  <fpizlo@apple.com>
 
         DFG::DCEPhase inserts into an insertion set in reverse, causing hilarious basic block corruption if you kill a lot of NewArrays
index 3174567..0bcb4a0 100644 (file)
 #include "Options.h"
 #include <stdio.h>
 #include <string.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/StringBuilder.h>
 
 namespace JSC { namespace DFG {
 
-static FunctionWhitelist* functionWhitelist;
-
 FunctionWhitelist& FunctionWhitelist::ensureGlobalWhitelist()
 {
+    static LazyNeverDestroyed<FunctionWhitelist> functionWhitelist;
     static std::once_flag initializeWhitelistFlag;
     std::call_once(initializeWhitelistFlag, [] {
-        functionWhitelist = new FunctionWhitelist(Options::dfgFunctionWhitelistFile());
+        const char* functionWhitelistFile = Options::dfgFunctionWhitelistFile();
+        functionWhitelist.construct(functionWhitelistFile);
     });
-    return *functionWhitelist;
+    return functionWhitelist;
 }
 
 FunctionWhitelist::FunctionWhitelist(const char* filename)
index b58e1a5..8f05be8 100644 (file)
@@ -38,11 +38,11 @@ namespace DFG {
 class FunctionWhitelist {
 public:
     static FunctionWhitelist& ensureGlobalWhitelist();
+    explicit FunctionWhitelist(const char*);
 
     bool contains(CodeBlock*) const;
 
 private:
-    FunctionWhitelist(const char*);
     void parseFunctionNamesInFile(const char*);
 
     HashSet<String> m_entries;
index 4a7f312..28c030a 100644 (file)
@@ -1,3 +1,25 @@
+2014-05-31  Anders Carlsson  <andersca@apple.com>
+
+        Add a LazyNeverDestroyed class template and use it
+        https://bugs.webkit.org/show_bug.cgi?id=133425
+
+        Reviewed by Darin Adler.
+
+        LazyNeverDestroyed is similar to NeverDestroyed, except it's lazily constructed
+        by calling construct(). This makes it useful for using inside std::call_once functions.
+        
+        * wtf/Forward.h:
+        * wtf/NeverDestroyed.h:
+        (WTF::LazyNeverDestroyed::construct):
+        (WTF::LazyNeverDestroyed::operator T&):
+        (WTF::LazyNeverDestroyed::get):
+        (WTF::LazyNeverDestroyed::asPtr):
+        (WTF::LazyNeverDestroyed::MaybeRelax::MaybeRelax):
+        * wtf/mac/DeprecatedSymbolsUsedBySafari.mm:
+        (WTF::atomicallyInitializedStaticMutex):
+        * wtf/unicode/icu/CollatorICU.cpp:
+        (WTF::cachedCollatorMutex):
+
 2014-05-29  Alex Christensen  <achristensen@webkit.org>
 
         Enable css jit by default on arm64.
index 215247f..49a92c5 100644 (file)
@@ -26,6 +26,7 @@
 namespace WTF {
 
 template<typename T> class Function;
+template<typename T> class LazyNeverDestroyed;
 template<typename T> class NeverDestroyed;
 template<typename T> class OwnPtr;
 template<typename T> class PassOwnPtr;
@@ -60,6 +61,7 @@ using WTF::Decoder;
 using WTF::Encoder;
 using WTF::Function;
 using WTF::FunctionDispatcher;
+using WTF::LazyNeverDestroyed;
 using WTF::NeverDestroyed;
 using WTF::OwnPtr;
 using WTF::PassOwnPtr;
index 57152bd..cf4311f 100644 (file)
@@ -73,8 +73,56 @@ private:
     };
 };
 
+template<typename T> class LazyNeverDestroyed {
+    WTF_MAKE_NONCOPYABLE(LazyNeverDestroyed);
+
+public:
+    LazyNeverDestroyed() = default;
+
+    template<typename... Args>
+    void construct(Args&&... args)
+    {
+        ASSERT(!m_isConstructed);
+
+#if !ASSERT_DISABLED
+        m_isConstructed = true;
+#endif
+
+        MaybeRelax<T>(new (asPtr()) T(std::forward<Args>(args)...));
+    }
+
+    operator T&() { return *asPtr(); }
+    T& get() { return *asPtr(); }
+
+private:
+    typedef typename std::remove_const<T>::type* PointerType;
+
+    PointerType asPtr()
+    {
+        ASSERT(m_isConstructed);
+
+        return reinterpret_cast<PointerType>(&m_storage);
+    }
+
+    // FIXME: Investigate whether we should allocate a hunk of virtual memory
+    // and hand out chunks of it to NeverDestroyed instead, to reduce fragmentation.
+    typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type m_storage;
+
+    template <typename PtrType, bool ShouldRelax = std::is_base_of<RefCounted<PtrType>, PtrType>::value> struct MaybeRelax {
+        explicit MaybeRelax(PtrType*) { }
+    };
+    template <typename PtrType> struct MaybeRelax<PtrType, true> {
+        explicit MaybeRelax(PtrType* ptr) { ptr->relaxAdoptionRequirement(); }
+    };
+
+#if !ASSERT_DISABLED
+    bool m_isConstructed = false;
+#endif
+};
+
 } // namespace WTF;
 
+using WTF::LazyNeverDestroyed;
 using WTF::NeverDestroyed;
 
 #endif // NeverDestroyed_h
index 0f897d1..fe730e4 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "Functional.h"
 #include "MainThread.h"
+#include "NeverDestroyed.h"
 #include "StdLibExtras.h"
 #include <mutex>
 
@@ -47,12 +48,12 @@ void callOnMainThread(const Function<void ()>& function)
 static std::mutex& atomicallyInitializedStaticMutex()
 {
     static std::once_flag onceFlag;
-    static std::mutex* mutex;
+    static LazyNeverDestroyed<std::mutex> mutex;
     std::call_once(onceFlag, []{
-        mutex = std::make_unique<std::mutex>().release();
+        mutex.construct();
     });
 
-    return *mutex;
+    return mutex;
 }
 
 void lockAtomicallyInitializedStaticMutex()
index 6123351..44f77f1 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <mutex>
 #include <unicode/ucol.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/StringExtras.h>
 #include <wtf/text/StringView.h>
 
@@ -52,11 +53,13 @@ static bool cachedCollatorShouldSortLowercaseFirst;
 static std::mutex& cachedCollatorMutex()
 {
     static std::once_flag onceFlag;
-    static std::mutex* mutex;
+
+    static LazyNeverDestroyed<std::mutex> mutex;
     std::call_once(onceFlag, []{
-        mutex = std::make_unique<std::mutex>().release();
+        mutex.construct();
     });
-    return *mutex;
+
+    return mutex;
 }
 
 #if !(OS(DARWIN) && USE(CF))
index 4505e64..cc2bd78 100644 (file)
@@ -1,3 +1,27 @@
+2014-05-31  Anders Carlsson  <andersca@apple.com>
+
+        Add a LazyNeverDestroyed class template and use it
+        https://bugs.webkit.org/show_bug.cgi?id=133425
+
+        Reviewed by Darin Adler.
+
+        * Modules/webdatabase/DatabaseBackendBase.cpp:
+        (WebCore::guidMutex):
+        * crypto/CryptoAlgorithmRegistry.cpp:
+        (WebCore::registryMutex):
+        * inspector/WorkerDebuggerAgent.cpp:
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::isOnAccessControlResponseHeaderWhitelist):
+        * platform/network/NetworkStateNotifier.cpp:
+        (WebCore::networkStateNotifier):
+        * workers/DefaultSharedWorkerRepository.cpp:
+        (WebCore::DefaultSharedWorkerRepository::instance):
+        * workers/DefaultSharedWorkerRepository.h:
+        * workers/WorkerThread.cpp:
+        (WebCore::threadSetMutex):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::staticData):
+
 2014-06-01  Zalan Bujtas  <zalan@apple.com>
 
         Subpixel rendering: Selection gap produces a pixel line overlap on inline boxes.
index 56d3d81..2e538e0 100644 (file)
@@ -141,13 +141,13 @@ static bool setTextValueInDatabase(SQLiteDatabase& db, const String& query, cons
 static std::mutex& guidMutex()
 {
     static std::once_flag onceFlag;
-    static std::mutex* mutex;
+    static LazyNeverDestroyed<std::mutex> mutex;
 
     std::call_once(onceFlag, []{
-        mutex = std::make_unique<std::mutex>().release();
+        mutex.construct();
     });
 
-    return *mutex;
+    return mutex;
 }
 
 typedef HashMap<DatabaseGuid, String> GuidVersionMap;
index 9842306..7f4eee3 100644 (file)
@@ -44,13 +44,13 @@ CryptoAlgorithmRegistry& CryptoAlgorithmRegistry::shared()
 static std::mutex& registryMutex()
 {
     static std::once_flag onceFlag;
-    static std::mutex* mutex;
+    static LazyNeverDestroyed<std::mutex> mutex;
 
     std::call_once(onceFlag, []{
-        mutex = std::make_unique<std::mutex>().release();
+        mutex.construct();
     });
 
-    return *mutex;
+    return mutex;
 }
 
 CryptoAlgorithmRegistry::CryptoAlgorithmRegistry()
index 611c519..0433657 100644 (file)
@@ -51,13 +51,13 @@ namespace {
 std::mutex& workerDebuggerAgentsMutex()
 {
     static std::once_flag onceFlag;
-    static std::mutex* mutex;
+    static LazyNeverDestroyed<std::mutex> mutex;
 
     std::call_once(onceFlag, []{
-        mutex = std::make_unique<std::mutex>().release();
+        mutex.construct();
     });
 
-    return *mutex;
+    return mutex;
 }
 
 typedef HashMap<WorkerThread*, WorkerDebuggerAgent*> WorkerDebuggerAgents;
index 852ac6d..345e7f5 100644 (file)
@@ -32,6 +32,7 @@
 #include "ResourceResponse.h"
 #include "SecurityOrigin.h"
 #include <mutex>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/AtomicString.h>
 #include <wtf/text/StringBuilder.h>
 
@@ -78,20 +79,20 @@ bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&
 bool isOnAccessControlResponseHeaderWhitelist(const String& name)
 {
     static std::once_flag onceFlag;
-    static HTTPHeaderSet* allowedCrossOriginResponseHeaders;
+    static LazyNeverDestroyed<HTTPHeaderSet> allowedCrossOriginResponseHeaders;
 
     std::call_once(onceFlag, []{
-        allowedCrossOriginResponseHeaders = std::make_unique<HTTPHeaderSet, std::initializer_list<String>>({
+        allowedCrossOriginResponseHeaders.construct<std::initializer_list<String>>({
             "cache-control",
             "content-language",
             "content-type",
             "expires",
             "last-modified",
             "pragma"
-        }).release();
+        });
     });
 
-    return allowedCrossOriginResponseHeaders->contains(name);
+    return allowedCrossOriginResponseHeaders.get().contains(name);
 }
 
 void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, StoredCredentials allowCredentials)
index b9e98f8..7540a78 100644 (file)
 
 #include <mutex>
 #include <wtf/Assertions.h>
-#include <wtf/StdLibExtras.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
 NetworkStateNotifier& networkStateNotifier()
 {
     static std::once_flag onceFlag;
-    static NetworkStateNotifier* networkStateNotifier;
+    static LazyNeverDestroyed<NetworkStateNotifier> networkStateNotifier;
 
     std::call_once(onceFlag, []{
-        networkStateNotifier = std::make_unique<NetworkStateNotifier>().release();
+        networkStateNotifier.construct();
     });
 
-    return *networkStateNotifier;
+    return networkStateNotifier;
 }
 
 void NetworkStateNotifier::addNetworkStateChangeListener(std::function<void (bool)> listener)
index 0979064..4bd8c57 100644 (file)
@@ -58,6 +58,7 @@
 #include <inspector/ScriptCallStack.h>
 #include <mutex>
 #include <wtf/HashSet.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/Threading.h>
 #include <wtf/text/WTFString.h>
 
@@ -331,12 +332,12 @@ void SharedWorkerScriptLoader::notifyFinished()
 DefaultSharedWorkerRepository& DefaultSharedWorkerRepository::instance()
 {
     static std::once_flag onceFlag;
-    static DefaultSharedWorkerRepository* instance;
+    static LazyNeverDestroyed<DefaultSharedWorkerRepository> instance;
     std::call_once(onceFlag, []{
-        instance = new DefaultSharedWorkerRepository;
+        instance.construct();
     });
 
-    return *instance;
+    return instance;
 }
 
 bool DefaultSharedWorkerRepository::isAvailable()
index 8818303..250ebe5 100644 (file)
@@ -57,6 +57,7 @@ namespace WebCore {
     // Platform-specific implementation of the SharedWorkerRepository static interface.
     class DefaultSharedWorkerRepository {
         WTF_MAKE_NONCOPYABLE(DefaultSharedWorkerRepository); WTF_MAKE_FAST_ALLOCATED;
+
     public:
         // Returns true if the platform supports SharedWorkers, otherwise false.
         static bool isAvailable();
@@ -76,8 +77,9 @@ namespace WebCore {
         bool hasSharedWorkers(Document*);
 
         static DefaultSharedWorkerRepository& instance();
-    private:
         DefaultSharedWorkerRepository();
+
+    private:
         ~DefaultSharedWorkerRepository();
 
         PassRefPtr<SharedWorkerProxy> getProxy(const String& name, const URL&);
index 264cf1b..b600770 100644 (file)
@@ -54,13 +54,13 @@ namespace WebCore {
 static std::mutex& threadSetMutex()
 {
     static std::once_flag onceFlag;
-    static std::mutex* mutex;
+    static LazyNeverDestroyed<std::mutex> mutex;
 
     std::call_once(onceFlag, []{
-        mutex = std::make_unique<std::mutex>().release();
+        mutex.construct();
     });
 
-    return *mutex;
+    return mutex;
 }
 
 static HashSet<WorkerThread*>& workerThreads()
index 4d27845..39260b8 100644 (file)
@@ -56,6 +56,7 @@
 #include <runtime/ArrayBufferView.h>
 #include <runtime/JSCInlines.h>
 #include <runtime/JSLock.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>
@@ -118,13 +119,13 @@ XMLHttpRequestStaticData::XMLHttpRequestStaticData()
 static const XMLHttpRequestStaticData& staticData()
 {
     static std::once_flag onceFlag;
-    static const XMLHttpRequestStaticData* staticData;
+    static LazyNeverDestroyed<XMLHttpRequestStaticData> staticData;
 
     std::call_once(onceFlag, [] {
-        staticData = std::make_unique<XMLHttpRequestStaticData>().release();
+        staticData.construct();
     });
 
-    return *staticData;
+    return staticData;
 }
 
 static bool isSetCookieHeader(const AtomicString& name)
index 298d3d0..ac75eb7 100644 (file)
@@ -1,3 +1,13 @@
+2014-05-31  Anders Carlsson  <andersca@apple.com>
+
+        Add a LazyNeverDestroyed class template and use it
+        https://bugs.webkit.org/show_bug.cgi?id=133425
+
+        Reviewed by Darin Adler.
+
+        * Shared/mac/SecItemShim.cpp:
+        (WebKit::responseMap):
+
 2014-05-31  Timothy Horton  <timothy_horton@apple.com>
 
         View snapshots are sometimes taken at the wrong scale
index cda70a5..b4a291b 100644 (file)
 #include <atomic>
 #include <dlfcn.h>
 #include <mutex>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebKit {
 
 static BlockingResponseMap<SecItemResponseData>& responseMap()
 {
     static std::once_flag onceFlag;
-    static BlockingResponseMap<SecItemResponseData>* responseMap;
+    static LazyNeverDestroyed<BlockingResponseMap<SecItemResponseData>> responseMap;
 
     std::call_once(onceFlag, []{
-        responseMap = std::make_unique<BlockingResponseMap<SecItemResponseData>>().release();
+        responseMap.construct();
     });
 
-    return *responseMap;
+    return responseMap;
 }
 
 static ChildProcess* sharedProcess;