Improve use of NeverDestroyed
[WebKit-https.git] / Source / WebCore / page / PerformanceUserTiming.cpp
index 016c9a2..ca3610d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Intel Inc. All rights reserved.
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "Document.h"
 #include "ExceptionCode.h"
-#include "Performance.h"
 #include "PerformanceTiming.h"
-#include <array>
-#include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
-#include <wtf/dtoa/utils.h>
 
 namespace WebCore {
 
-namespace {
-
-typedef unsigned long long (PerformanceTiming::*NavigationTimingFunction)() const;
+using NavigationTimingFunction = unsigned long long (PerformanceTiming::*)() const;
 
 static NavigationTimingFunction restrictedMarkFunction(const String& markName)
 {
     ASSERT(isMainThread());
 
-    using MapPair = std::pair<ASCIILiteral, NavigationTimingFunction>;
-    static const std::array<MapPair, 21> pairs = { {
-        MapPair { ASCIILiteral("navigationStart"), &PerformanceTiming::navigationStart },
-        MapPair { ASCIILiteral("unloadEventStart"), &PerformanceTiming::unloadEventStart },
-        MapPair { ASCIILiteral("unloadEventEnd"), &PerformanceTiming::unloadEventEnd },
-        MapPair { ASCIILiteral("redirectStart"), &PerformanceTiming::redirectStart },
-        MapPair { ASCIILiteral("redirectEnd"), &PerformanceTiming::redirectEnd },
-        MapPair { ASCIILiteral("fetchStart"), &PerformanceTiming::fetchStart },
-        MapPair { ASCIILiteral("domainLookupStart"), &PerformanceTiming::domainLookupStart },
-        MapPair { ASCIILiteral("domainLookupEnd"), &PerformanceTiming::domainLookupEnd },
-        MapPair { ASCIILiteral("connectStart"), &PerformanceTiming::connectStart },
-        MapPair { ASCIILiteral("connectEnd"), &PerformanceTiming::connectEnd },
-        MapPair { ASCIILiteral("secureConnectionStart"), &PerformanceTiming::secureConnectionStart },
-        MapPair { ASCIILiteral("requestStart"), &PerformanceTiming::requestStart },
-        MapPair { ASCIILiteral("responseStart"), &PerformanceTiming::responseStart },
-        MapPair { ASCIILiteral("responseEnd"), &PerformanceTiming::responseEnd },
-        MapPair { ASCIILiteral("domLoading"), &PerformanceTiming::domLoading },
-        MapPair { ASCIILiteral("domInteractive"), &PerformanceTiming::domInteractive },
-        MapPair { ASCIILiteral("domContentLoadedEventStart"), &PerformanceTiming::domContentLoadedEventStart },
-        MapPair { ASCIILiteral("domContentLoadedEventEnd"), &PerformanceTiming::domContentLoadedEventEnd },
-        MapPair { ASCIILiteral("domComplete"), &PerformanceTiming::domComplete },
-        MapPair { ASCIILiteral("loadEventStart"), &PerformanceTiming::loadEventStart },
-        MapPair { ASCIILiteral("loadEventEnd"), &PerformanceTiming::loadEventEnd },
-    } };
-
-    static NeverDestroyed<HashMap<String, NavigationTimingFunction>> map;
-    if (map.get().isEmpty()) {
+    static const auto map = makeNeverDestroyed([] {
+        static const std::pair<const char*, NavigationTimingFunction> pairs[] = {
+            { "connectEnd", &PerformanceTiming::connectEnd },
+            { "connectStart", &PerformanceTiming::connectStart },
+            { "domComplete", &PerformanceTiming::domComplete },
+            { "domContentLoadedEventEnd", &PerformanceTiming::domContentLoadedEventEnd },
+            { "domContentLoadedEventStart", &PerformanceTiming::domContentLoadedEventStart },
+            { "domInteractive", &PerformanceTiming::domInteractive },
+            { "domLoading", &PerformanceTiming::domLoading },
+            { "domainLookupEnd", &PerformanceTiming::domainLookupEnd },
+            { "domainLookupStart", &PerformanceTiming::domainLookupStart },
+            { "fetchStart", &PerformanceTiming::fetchStart },
+            { "loadEventEnd", &PerformanceTiming::loadEventEnd },
+            { "loadEventStart", &PerformanceTiming::loadEventStart },
+            { "navigationStart", &PerformanceTiming::navigationStart },
+            { "redirectEnd", &PerformanceTiming::redirectEnd },
+            { "redirectStart", &PerformanceTiming::redirectStart },
+            { "requestStart", &PerformanceTiming::requestStart },
+            { "responseEnd", &PerformanceTiming::responseEnd },
+            { "responseStart", &PerformanceTiming::responseStart },
+            { "secureConnectionStart", &PerformanceTiming::secureConnectionStart },
+            { "unloadEventEnd", &PerformanceTiming::unloadEventEnd },
+            { "unloadEventStart", &PerformanceTiming::unloadEventStart },
+        };
+        HashMap<String, NavigationTimingFunction> map;
         for (auto& pair : pairs)
-            map.get().add(pair.first, pair.second);
-    }
+            map.add(ASCIILiteral { pair.first }, pair.second);
+        return map;
+    }());
 
     return map.get().get(markName);
 }
 
-} // namespace anonymous
-
 UserTiming::UserTiming(Performance& performance)
     : m_performance(performance)
 {
 }
 
-static void clearPerformanceEntries(PerformanceEntryMap& performanceEntryMap, const String& name)
+static void clearPerformanceEntries(PerformanceEntryMap& map, const String& name)
 {
-    if (name.isNull()) {
-        performanceEntryMap.clear();
-        return;
-    }
-
-    performanceEntryMap.remove(name);
+    if (name.isNull())
+        map.clear();
+    else
+        map.remove(name);
 }
 
 ExceptionOr<Ref<PerformanceMark>> UserTiming::mark(const String& markName)
 {
-    if (is<Document>(m_performance.scriptExecutionContext())) {
-        if (restrictedMarkFunction(markName))
-            return Exception { SYNTAX_ERR };
-    }
+    if (is<Document>(m_performance.scriptExecutionContext()) && restrictedMarkFunction(markName))
+        return Exception { SYNTAX_ERR };
 
     auto& performanceEntryList = m_marksMap.ensure(markName, [] { return Vector<RefPtr<PerformanceEntry>>(); }).iterator->value;
     auto entry = PerformanceMark::create(markName, m_performance.now());
@@ -118,15 +106,16 @@ void UserTiming::clearMarks(const String& markName)
 
 ExceptionOr<double> UserTiming::findExistingMarkStartTime(const String& markName)
 {
-    if (m_marksMap.contains(markName))
-        return m_marksMap.get(markName).last()->startTime();
+    auto iterator = m_marksMap.find(markName);
+    if (iterator != m_marksMap.end())
+        return iterator->value.last()->startTime();
 
-    PerformanceTiming* timing = m_performance.timing();
+    auto* timing = m_performance.timing();
     if (!timing)
         return Exception { SYNTAX_ERR, makeString("No mark named '", markName, "' exists") };
 
     if (auto function = restrictedMarkFunction(markName)) {
-        double value = static_cast<double>(((*timing).*(function))());
+        double value = ((*timing).*(function))();
         if (!value)
             return Exception { INVALID_ACCESS_ERR };
         return value - timing->navigationStart();
@@ -170,19 +159,14 @@ void UserTiming::clearMeasures(const String& measureName)
     clearPerformanceEntries(m_measuresMap, measureName);
 }
 
-static Vector<RefPtr<PerformanceEntry>> convertToEntrySequence(const PerformanceEntryMap& performanceEntryMap)
+static Vector<RefPtr<PerformanceEntry>> convertToEntrySequence(const PerformanceEntryMap& map)
 {
     Vector<RefPtr<PerformanceEntry>> entries;
-    for (auto& entry : performanceEntryMap.values())
+    for (auto& entry : map.values())
         entries.appendVector(entry);
     return entries;
 }
 
-static Vector<RefPtr<PerformanceEntry>> getEntrySequenceByName(const PerformanceEntryMap& performanceEntryMap, const String& name)
-{
-    return performanceEntryMap.get(name);
-}
-
 Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks() const
 {
     return convertToEntrySequence(m_marksMap);
@@ -190,7 +174,7 @@ Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks() const
 
 Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks(const String& name) const
 {
-    return getEntrySequenceByName(m_marksMap, name);
+    return m_marksMap.get(name);
 }
 
 Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures() const
@@ -200,7 +184,7 @@ Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures() const
 
 Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures(const String& name) const
 {
-    return getEntrySequenceByName(m_measuresMap, name);
+    return m_measuresMap.get(name);
 }
 
 } // namespace WebCore