[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

tonyg at chromium.org tonyg at chromium.org
Wed Dec 22 11:19:56 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 83c94c4c00251c6a8132980837a2096cb78b5bad
Author: tonyg at chromium.org <tonyg at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Jul 19 21:55:13 2010 +0000

    2010-07-17  Tony Gentilcore  <tonyg at chromium.org>
    
            Reviewed by Darin Fisher.
    
            [Web Timing] Move times to DocumentLoader and fix bugs in mark points
            https://bugs.webkit.org/show_bug.cgi?id=42512
    
            * fast/dom/script-tests/webtiming-navigate-within-document.js: Added. Previously, navigating within a document via a fragment would reset navigationStart. This test verifies that no times are changed after navigating within a document.
            (checkTimingNotChanged):
            ():
            (loadHandler):
            * fast/dom/webtiming-expected.txt: Test now passes because when correcting for clock skew, requestTime is set to fetchStart when it is less than fetchStart. Previously it was 0, now it is fetchStart. This, unfortunately, hides the fact that test_shell isn't populating the ResourceLoadTiming API. I'll think of a way to test that when I make the change to cause test_shell to fill the ResourceLoadTiming.
            * fast/dom/webtiming-navigate-within-document-expected.txt: Added.
            * fast/dom/webtiming-navigate-within-document.html: Added.
            * platform/gtk/Skipped: Skip new test on platform where Web Timing is not enabled.
            * platform/mac/Skipped: Skip new test on platform where Web Timing is not enabled.
            * platform/qt/Skipped: Skip new test on platform where Web Timing is not enabled.
            * platform/win/Skipped: Skip new test on platform where Web Timing is not enabled.
    2010-07-17  Tony Gentilcore  <tonyg at chromium.org>
    
            Reviewed by Darin Fisher.
    
            [Web Timing] Move times to DocumentLoader and fix bugs in mark points
            https://bugs.webkit.org/show_bug.cgi?id=42512
    
            Test: fast/dom/webtiming-navigate-within-document.html
    
            * loader/DocumentLoader.h: Move the FrameLoadTimeline (now call DocumentLoadTiming) to the DocumentLoader.
            (WebCore::DocumentLoader::documentLoadTiming):
            * loader/FrameLoader.cpp:
            (WebCore::FrameLoader::stopLoading): Set unloadEventEnd on the provisional DocumentLoader. Add some ASSERTs to tighten things up.
            (WebCore::FrameLoader::loadWithDocumentLoader): This was not the right place to set navigationStart. Setting it here caused it to be set before the unload form prompt and caused it to be reset when navigating within the document.
            (WebCore::FrameLoader::finishedLoading): Set responseEnd on the active DocumentLoader.
            (WebCore::FrameLoader::continueLoadAfterWillSubmitForm): This is the right place for navigationStart as defined by the spec.
            * loader/FrameLoader.h: Get rid of FrameLoadTimeline.
            * loader/FrameLoaderTypes.h: Rename FrameLoadTimeline to DocumentLoadTiming. It is even more apparent this doesn't belong in this file now. I am planning to submit a patch moving it out ASAP, but didn't want to muddy this patch with all those build files.
            (WebCore::DocumentLoadTiming::DocumentLoadTiming):
            * loader/MainResourceLoader.cpp:
            (WebCore::MainResourceLoader::willSendRequest): Move fetchStart out of this method to load(), and rewrite setting of redirectStart, redirectEnd, and redirectCount to be more readable.
            (WebCore::MainResourceLoader::load): Set fetchStart slightly earlier here and tighten it up with some ASSERTs.
            * page/DOMWindow.cpp:
            (WebCore::DOMWindow::dispatchLoadEvent): Set loadEventStart and loadEventEnd on the DocumentLoader.
            * page/Navigation.cpp:
            (WebCore::Navigation::redirectCount): Retrieve redirectCount from the DocumentLoader.
            * page/Timing.cpp:
            (WebCore::getPossiblySkewedTimeInKnownRange): The skew problem turned out to be due to the fact that chromium's currentTime() implementation only syncs to the system time every 60 seconds. So absolute times across threads may be skewed slightly. I resolved this temporarily by clipping the time from another thread into a known bound. A better long term solution is probably to add a currentTimeFromSystemTime() method and call that for web timing marks.
            (WebCore::Timing::navigationStart):
            (WebCore::Timing::unloadEventEnd):
            (WebCore::Timing::redirectStart):
            (WebCore::Timing::redirectEnd):
            (WebCore::Timing::fetchStart):
            (WebCore::Timing::domainLookupStart):
            (WebCore::Timing::domainLookupEnd):
            (WebCore::Timing::connectStart):
            (WebCore::Timing::connectEnd):
            (WebCore::Timing::requestStart):
            (WebCore::Timing::requestEnd):
            (WebCore::Timing::responseStart):
            (WebCore::Timing::responseEnd):
            (WebCore::Timing::loadEventStart):
            (WebCore::Timing::loadEventEnd):
            (WebCore::Timing::documentLoader):
            (WebCore::Timing::documentLoadTiming):
            (WebCore::Timing::resourceLoadTiming):
            (WebCore::Timing::resourceLoadTimeRelativeToAbsolute): Ensure requestTime is in the range of fetchStart to responseEnd.
            * page/Timing.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63689 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index ce75d6f..cf71352 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2010-07-17  Tony Gentilcore  <tonyg at chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        [Web Timing] Move times to DocumentLoader and fix bugs in mark points
+        https://bugs.webkit.org/show_bug.cgi?id=42512
+
+        * fast/dom/script-tests/webtiming-navigate-within-document.js: Added. Previously, navigating within a document via a fragment would reset navigationStart. This test verifies that no times are changed after navigating within a document.
+        (checkTimingNotChanged):
+        ():
+        (loadHandler):
+        * fast/dom/webtiming-expected.txt: Test now passes because when correcting for clock skew, requestTime is set to fetchStart when it is less than fetchStart. Previously it was 0, now it is fetchStart. This, unfortunately, hides the fact that test_shell isn't populating the ResourceLoadTiming API. I'll think of a way to test that when I make the change to cause test_shell to fill the ResourceLoadTiming.
+        * fast/dom/webtiming-navigate-within-document-expected.txt: Added.
+        * fast/dom/webtiming-navigate-within-document.html: Added.
+        * platform/gtk/Skipped: Skip new test on platform where Web Timing is not enabled.
+        * platform/mac/Skipped: Skip new test on platform where Web Timing is not enabled.
+        * platform/qt/Skipped: Skip new test on platform where Web Timing is not enabled.
+        * platform/win/Skipped: Skip new test on platform where Web Timing is not enabled.
+
 2010-07-19  Eric Carlson  <eric.carlson at apple.com>
 
         Unreviewed, build fix.
diff --git a/LayoutTests/fast/dom/script-tests/webtiming-navigate-within-document.js b/LayoutTests/fast/dom/script-tests/webtiming-navigate-within-document.js
new file mode 100644
index 0000000..ab583bd
--- /dev/null
+++ b/LayoutTests/fast/dom/script-tests/webtiming-navigate-within-document.js
@@ -0,0 +1,36 @@
+description("This test checks that navigating within the document does not reset Web Timing numbers.");
+
+var performance = window.webkitPerformance || {};
+var timing = performance.timing || {};
+
+function checkTimingNotChanged()
+{
+    for (var property in timing) {
+        if (timing[property] === initialTiming[property])
+            testPassed(property + " is unchanged.");
+        else
+            testFailed(property + " changed.");
+    }
+    finishJSTest();
+}
+
+var initialTiming = {};
+function saveTimingAfterLoad()
+{
+    for (var property in timing) {
+        initialTiming[property] = timing[property];
+    }
+    window.location.href = "#1";
+    setTimeout("checkTimingNotChanged()", 0);
+}
+
+function loadHandler()
+{
+    window.removeEventListener("load", loadHandler);
+    setTimeout("saveTimingAfterLoad()", 0);
+}
+window.addEventListener("load", loadHandler, false);
+
+jsTestIsAsync = true;
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/webtiming-expected.txt b/LayoutTests/fast/dom/webtiming-expected.txt
index 5393673..1e8951c 100644
--- a/LayoutTests/fast/dom/webtiming-expected.txt
+++ b/LayoutTests/fast/dom/webtiming-expected.txt
@@ -13,7 +13,7 @@ PASS timing.domainLookupStart is >= timing.fetchStart
 PASS timing.domainLookupEnd is >= timing.domainLookupStart
 PASS timing.connectStart is >= timing.domainLookupEnd
 PASS timing.connectEnd is >= timing.connectStart
-FAIL timing.requestStart should be >= timing.connectEnd. Was 0 (of type number).
+PASS timing.requestStart is >= timing.connectEnd
 PASS timing.requestEnd is >= timing.requestStart
 PASS timing.responseStart is >= timing.requestEnd
 PASS timing.loadEventStart is 0
@@ -28,7 +28,7 @@ PASS timing.domainLookupStart is >= timing.fetchStart
 PASS timing.domainLookupEnd is >= timing.domainLookupStart
 PASS timing.connectStart is >= timing.domainLookupEnd
 PASS timing.connectEnd is >= timing.connectStart
-FAIL timing.requestStart should be >= timing.connectEnd. Was 0 (of type number).
+PASS timing.requestStart is >= timing.connectEnd
 PASS timing.requestEnd is >= timing.requestStart
 PASS timing.responseStart is >= timing.requestEnd
 PASS timing.responseEnd is >= timing.responseStart
@@ -44,7 +44,7 @@ PASS timing.domainLookupStart is >= timing.fetchStart
 PASS timing.domainLookupEnd is >= timing.domainLookupStart
 PASS timing.connectStart is >= timing.domainLookupEnd
 PASS timing.connectEnd is >= timing.connectStart
-FAIL timing.requestStart should be >= timing.connectEnd. Was 0 (of type number).
+PASS timing.requestStart is >= timing.connectEnd
 PASS timing.requestEnd is >= timing.requestStart
 PASS timing.responseStart is >= timing.requestEnd
 PASS timing.responseEnd is >= timing.responseStart
diff --git a/LayoutTests/fast/dom/webtiming-navigate-within-document-expected.txt b/LayoutTests/fast/dom/webtiming-navigate-within-document-expected.txt
new file mode 100644
index 0000000..22aefd2
--- /dev/null
+++ b/LayoutTests/fast/dom/webtiming-navigate-within-document-expected.txt
@@ -0,0 +1,24 @@
+This test checks that navigating within the document does not reset Web Timing numbers.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS requestEnd is unchanged.
+PASS responseStart is unchanged.
+PASS connectStart is unchanged.
+PASS domainLookupStart is unchanged.
+PASS connectEnd is unchanged.
+PASS responseEnd is unchanged.
+PASS requestStart is unchanged.
+PASS navigationStart is unchanged.
+PASS loadEventEnd is unchanged.
+PASS redirectStart is unchanged.
+PASS domainLookupEnd is unchanged.
+PASS unloadEventEnd is unchanged.
+PASS fetchStart is unchanged.
+PASS loadEventStart is unchanged.
+PASS redirectEnd is unchanged.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/webtiming-navigate-within-document.html b/LayoutTests/fast/dom/webtiming-navigate-within-document.html
new file mode 100644
index 0000000..1984aa9
--- /dev/null
+++ b/LayoutTests/fast/dom/webtiming-navigate-within-document.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/webtiming-navigate-within-document.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/gtk/Skipped b/LayoutTests/platform/gtk/Skipped
index 4959a94..c2e2649 100644
--- a/LayoutTests/platform/gtk/Skipped
+++ b/LayoutTests/platform/gtk/Skipped
@@ -5864,5 +5864,6 @@ fast/dom/navigation-type-back-forward.html
 fast/dom/navigation-type-navigate.html
 fast/dom/navigation-type-reload.html
 fast/dom/webtiming.html
+fast/dom/webtiming-navigate-within-document.html
 http/tests/misc/webtiming-one-redirect.php
 http/tests/misc/webtiming-two-redirects.php
diff --git a/LayoutTests/platform/mac/Skipped b/LayoutTests/platform/mac/Skipped
index e046092..cfc9c48 100644
--- a/LayoutTests/platform/mac/Skipped
+++ b/LayoutTests/platform/mac/Skipped
@@ -290,5 +290,6 @@ fast/dom/navigation-type-back-forward.html
 fast/dom/navigation-type-navigate.html
 fast/dom/navigation-type-reload.html
 fast/dom/webtiming.html
+fast/dom/webtiming-navigate-within-document.html
 http/tests/misc/webtiming-one-redirect.php
 http/tests/misc/webtiming-two-redirects.php
diff --git a/LayoutTests/platform/qt/Skipped b/LayoutTests/platform/qt/Skipped
index 7932cd5..2571ae4 100644
--- a/LayoutTests/platform/qt/Skipped
+++ b/LayoutTests/platform/qt/Skipped
@@ -5449,6 +5449,7 @@ fast/dom/navigation-type-back-forward.html
 fast/dom/navigation-type-navigate.html
 fast/dom/navigation-type-reload.html
 fast/dom/webtiming.html
+fast/dom/webtiming-navigate-within-document.html
 http/tests/misc/webtiming-one-redirect.php
 http/tests/misc/webtiming-two-redirects.php
 
diff --git a/LayoutTests/platform/win/Skipped b/LayoutTests/platform/win/Skipped
index 70268b2..e506cea 100644
--- a/LayoutTests/platform/win/Skipped
+++ b/LayoutTests/platform/win/Skipped
@@ -958,6 +958,7 @@ fast/dom/navigation-type-back-forward.html
 fast/dom/navigation-type-navigate.html
 fast/dom/navigation-type-reload.html
 fast/dom/webtiming.html
+fast/dom/webtiming-navigate-within-document.html
 http/tests/misc/webtiming-one-redirect.php
 http/tests/misc/webtiming-two-redirects.php
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 003a79d..169d87f 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,52 @@
+2010-07-17  Tony Gentilcore  <tonyg at chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        [Web Timing] Move times to DocumentLoader and fix bugs in mark points
+        https://bugs.webkit.org/show_bug.cgi?id=42512
+
+        Test: fast/dom/webtiming-navigate-within-document.html
+
+        * loader/DocumentLoader.h: Move the FrameLoadTimeline (now call DocumentLoadTiming) to the DocumentLoader.
+        (WebCore::DocumentLoader::documentLoadTiming):
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::stopLoading): Set unloadEventEnd on the provisional DocumentLoader. Add some ASSERTs to tighten things up.
+        (WebCore::FrameLoader::loadWithDocumentLoader): This was not the right place to set navigationStart. Setting it here caused it to be set before the unload form prompt and caused it to be reset when navigating within the document.
+        (WebCore::FrameLoader::finishedLoading): Set responseEnd on the active DocumentLoader.
+        (WebCore::FrameLoader::continueLoadAfterWillSubmitForm): This is the right place for navigationStart as defined by the spec.
+        * loader/FrameLoader.h: Get rid of FrameLoadTimeline.
+        * loader/FrameLoaderTypes.h: Rename FrameLoadTimeline to DocumentLoadTiming. It is even more apparent this doesn't belong in this file now. I am planning to submit a patch moving it out ASAP, but didn't want to muddy this patch with all those build files.
+        (WebCore::DocumentLoadTiming::DocumentLoadTiming):
+        * loader/MainResourceLoader.cpp:
+        (WebCore::MainResourceLoader::willSendRequest): Move fetchStart out of this method to load(), and rewrite setting of redirectStart, redirectEnd, and redirectCount to be more readable.
+        (WebCore::MainResourceLoader::load): Set fetchStart slightly earlier here and tighten it up with some ASSERTs.
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::dispatchLoadEvent): Set loadEventStart and loadEventEnd on the DocumentLoader.
+        * page/Navigation.cpp:
+        (WebCore::Navigation::redirectCount): Retrieve redirectCount from the DocumentLoader.
+        * page/Timing.cpp:
+        (WebCore::getPossiblySkewedTimeInKnownRange): The skew problem turned out to be due to the fact that chromium's currentTime() implementation only syncs to the system time every 60 seconds. So absolute times across threads may be skewed slightly. I resolved this temporarily by clipping the time from another thread into a known bound. A better long term solution is probably to add a currentTimeFromSystemTime() method and call that for web timing marks.
+        (WebCore::Timing::navigationStart):
+        (WebCore::Timing::unloadEventEnd):
+        (WebCore::Timing::redirectStart):
+        (WebCore::Timing::redirectEnd):
+        (WebCore::Timing::fetchStart):
+        (WebCore::Timing::domainLookupStart):
+        (WebCore::Timing::domainLookupEnd):
+        (WebCore::Timing::connectStart):
+        (WebCore::Timing::connectEnd):
+        (WebCore::Timing::requestStart):
+        (WebCore::Timing::requestEnd):
+        (WebCore::Timing::responseStart):
+        (WebCore::Timing::responseEnd):
+        (WebCore::Timing::loadEventStart):
+        (WebCore::Timing::loadEventEnd):
+        (WebCore::Timing::documentLoader):
+        (WebCore::Timing::documentLoadTiming):
+        (WebCore::Timing::resourceLoadTiming):
+        (WebCore::Timing::resourceLoadTimeRelativeToAbsolute): Ensure requestTime is in the range of fetchStart to responseEnd.
+        * page/Timing.h:
+
 2010-07-19  Chris Marrin  <cmarrin at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/loader/DocumentLoader.h b/WebCore/loader/DocumentLoader.h
index 5cc1cdc..da9b4ee 100644
--- a/WebCore/loader/DocumentLoader.h
+++ b/WebCore/loader/DocumentLoader.h
@@ -205,6 +205,8 @@ namespace WebCore {
         void recordMemoryCacheLoadForFutureClientNotification(const String& url);
         void takeMemoryCacheLoadsForClientNotification(Vector<String>& loads);
 
+        DocumentLoadTiming* timing() { return &m_documentLoadTiming; }
+
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
         ApplicationCacheHost* applicationCacheHost() const { return m_applicationCacheHost.get(); }
 #endif
@@ -294,6 +296,8 @@ namespace WebCore {
         String m_clientRedirectSourceForHistory;
         bool m_didCreateGlobalHistoryEntry;
 
+        DocumentLoadTiming m_documentLoadTiming;
+
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
         friend class ApplicationCacheHost;  // for substitute resource delivery
         OwnPtr<ApplicationCacheHost> m_applicationCacheHost;
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 361e9cd..1465973 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -449,7 +449,13 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
                         m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
                     if (!m_frame->document()->inPageCache())
                         m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document());
-                    m_frameLoadTimeline.unloadEventEnd = currentTime();
+                    if (m_provisionalDocumentLoader) {
+                        DocumentLoadTiming* timing = m_provisionalDocumentLoader->timing();
+                        ASSERT(timing->navigationStart);
+                        ASSERT(!timing->unloadEventEnd);
+                        timing->unloadEventEnd = currentTime();
+                        ASSERT(timing->unloadEventEnd >= timing->navigationStart);
+                    }
                 }
                 m_pageDismissalEventBeingDispatched = false;
                 if (m_frame->document())
@@ -1500,9 +1506,6 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
     if (m_pageDismissalEventBeingDispatched)
         return;
 
-    m_frameLoadTimeline = FrameLoadTimeline();
-    m_frameLoadTimeline.navigationStart = currentTime();
-
     policyChecker()->setLoadType(type);
     RefPtr<FormState> formState = prpFormState;
     bool isFormSubmission = formState;
@@ -2215,10 +2218,9 @@ void FrameLoader::finishedLoading()
     // Retain because the stop may release the last reference to it.
     RefPtr<Frame> protect(m_frame);
 
-    ASSERT(!m_frameLoadTimeline.responseEnd);
-    m_frameLoadTimeline.responseEnd = currentTime();
-
     RefPtr<DocumentLoader> dl = activeDocumentLoader();
+    ASSERT(!dl->timing()->responseEnd);
+    dl->timing()->responseEnd = currentTime();
     dl->finishedLoading();
     if (!dl->mainDocumentError().isNull() || !dl->frameLoader())
         return;
@@ -2509,6 +2511,9 @@ void FrameLoader::continueLoadAfterWillSubmitForm()
         notifier()->assignIdentifierToInitialRequest(identifier, m_provisionalDocumentLoader.get(), m_provisionalDocumentLoader->originalRequest());
     }
 
+    ASSERT(!m_provisionalDocumentLoader->timing()->navigationStart);
+    m_provisionalDocumentLoader->timing()->navigationStart = currentTime();
+
     if (!m_provisionalDocumentLoader->startLoadingMainResource(identifier))
         m_provisionalDocumentLoader->updateLoading();
 }
diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h
index 756ebc3..12b536b 100644
--- a/WebCore/loader/FrameLoader.h
+++ b/WebCore/loader/FrameLoader.h
@@ -193,7 +193,6 @@ public:
     void didChangeIcons(DocumentLoader*);
 
     FrameLoadType loadType() const;
-    FrameLoadTimeline* frameLoadTimeline() { return &m_frameLoadTimeline; }
 
     CachePolicy subresourceCachePolicy() const;
 
@@ -446,7 +445,6 @@ private:
 
     FrameState m_state;
     FrameLoadType m_loadType;
-    FrameLoadTimeline m_frameLoadTimeline;
 
     // Document loaders for the three phases of frame loading. Note that while 
     // a new request is being loaded, the old document loader may still be referenced.
diff --git a/WebCore/loader/FrameLoaderTypes.h b/WebCore/loader/FrameLoaderTypes.h
index ae671ce..387b067 100644
--- a/WebCore/loader/FrameLoaderTypes.h
+++ b/WebCore/loader/FrameLoaderTypes.h
@@ -60,9 +60,9 @@ namespace WebCore {
         FrameLoadTypeBackWMLDeckNotAccessible
     };
 
-    // FIXME: Move this to a new header file.
-    struct FrameLoadTimeline {
-        FrameLoadTimeline()
+    // FIXME: Move to DocumentLoadTiming.h.
+    struct DocumentLoadTiming {
+        DocumentLoadTiming()
             : navigationStart(0.0)
             , unloadEventEnd(0.0)
             , redirectStart(0.0)
diff --git a/WebCore/loader/MainResourceLoader.cpp b/WebCore/loader/MainResourceLoader.cpp
index dbc8f6d..504a5ea 100644
--- a/WebCore/loader/MainResourceLoader.cpp
+++ b/WebCore/loader/MainResourceLoader.cpp
@@ -159,14 +159,15 @@ void MainResourceLoader::willSendRequest(ResourceRequest& newRequest, const Reso
     // reference to this object; one example of this is 3266216.
     RefPtr<MainResourceLoader> protect(this);
 
-    FrameLoadTimeline* frameLoadTimeline = frameLoader()->frameLoadTimeline();
-    double fetchTime = currentTime();
-    if (double fetchStart = frameLoadTimeline->fetchStart) {
-        if (!frameLoadTimeline->redirectCount++)
-            frameLoadTimeline->redirectStart = fetchStart;
-        frameLoadTimeline->redirectEnd = fetchTime;
+    ASSERT(documentLoader()->timing()->fetchStart);
+    if (!redirectResponse.isNull()) {
+        DocumentLoadTiming* documentLoadTiming = documentLoader()->timing();
+        documentLoadTiming->redirectCount++;
+        if (!documentLoadTiming->redirectStart)
+            documentLoadTiming->redirectStart = documentLoadTiming->fetchStart;
+        documentLoadTiming->redirectEnd = currentTime();
+        documentLoadTiming->fetchStart = documentLoadTiming->redirectEnd;
     }
-    frameLoadTimeline->fetchStart = fetchTime;
 
     // Update cookie policy base URL as URL changes, except for subframes, which use the
     // URL of the main frame which doesn't change when we redirect.
@@ -542,6 +543,9 @@ bool MainResourceLoader::load(const ResourceRequest& r, const SubstituteData& su
 
     m_substituteData = substituteData;
 
+    ASSERT(documentLoader()->timing()->navigationStart);
+    ASSERT(!documentLoader()->timing()->fetchStart);
+    documentLoader()->timing()->fetchStart = currentTime();
     ResourceRequest request(r);
 
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 5ebe659..918a83a 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -35,6 +35,7 @@
 #include "CSSStyleSelector.h"
 #include "Chrome.h"
 #include "Console.h"
+#include "DocumentLoader.h"
 #include "DOMApplicationCache.h"
 #include "DOMSelection.h"
 #include "DOMTimer.h"
@@ -1438,11 +1439,11 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
 
 void DOMWindow::dispatchLoadEvent()
 {
-    if (m_frame)
-        m_frame->loader()->frameLoadTimeline()->loadEventStart = currentTime();
+    if (DocumentLoader* documentLoader = m_frame ? m_frame->loader()->documentLoader() : 0)
+        documentLoader->timing()->loadEventStart = currentTime();
     dispatchEvent(Event::create(eventNames().loadEvent, false, false), document());
-    if (m_frame)
-        m_frame->loader()->frameLoadTimeline()->loadEventEnd = currentTime();
+    if (DocumentLoader* documentLoader = m_frame ? m_frame->loader()->documentLoader() : 0)
+        documentLoader->timing()->loadEventEnd = currentTime();
 
     // For load events, send a separate load event to the enclosing frame only.
     // This is a DOM extension and is independent of bubbling/capturing rules of
diff --git a/WebCore/page/Navigation.cpp b/WebCore/page/Navigation.cpp
index 4fec0ee..ad93b47 100644
--- a/WebCore/page/Navigation.cpp
+++ b/WebCore/page/Navigation.cpp
@@ -79,7 +79,11 @@ unsigned short Navigation::redirectCount() const
     if (!m_frame)
         return 0;
 
-    return m_frame->loader()->frameLoadTimeline()->redirectCount;
+    DocumentLoader* loader = m_frame->loader()->documentLoader();
+    if (!loader)
+        return 0;
+
+    return loader->timing()->redirectCount;
 }
 
 } // namespace WebCore
diff --git a/WebCore/page/Timing.cpp b/WebCore/page/Timing.cpp
index e57e48a..527390a 100644
--- a/WebCore/page/Timing.cpp
+++ b/WebCore/page/Timing.cpp
@@ -40,10 +40,31 @@
 
 namespace WebCore {
 
-static unsigned long long toIntegerMilliseconds(double milliseconds)
+static unsigned long long toIntegerMilliseconds(double seconds)
 {
-    ASSERT(milliseconds >= 0);
-    return static_cast<unsigned long long>(milliseconds * 1000.0);
+    ASSERT(seconds >= 0);
+    return static_cast<unsigned long long>(seconds * 1000.0);
+}
+
+static double getPossiblySkewedTimeInKnownRange(double skewedTime, double lowerBound, double upperBound)
+{
+#if PLATFORM(CHROMIUM)
+    // The chromium port's currentTime() implementation only syncs with the
+    // system clock every 60 seconds. So it is possible for timing marks
+    // collected in different threads or processes to have a small skew.
+    // FIXME: It may be possible to add a currentTimeFromSystemTime() method
+    // that eliminates the skew.
+    if (skewedTime <= lowerBound)
+        return lowerBound;
+
+    if (skewedTime >= upperBound)
+        return upperBound;
+#else
+    ASSERT_UNUSED(lowerBound, skewedTime >= lowerBound);
+    ASSERT_UNUSED(upperBound, skewedTime <= upperBound);
+#endif
+
+    return skewedTime;
 }
 
 Timing::Timing(Frame* frame)
@@ -63,42 +84,47 @@ void Timing::disconnectFrame()
 
 unsigned long long Timing::navigationStart() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
 
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->navigationStart);
+    return toIntegerMilliseconds(timing->navigationStart);
 }
 
 unsigned long long Timing::unloadEventEnd() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
 
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->unloadEventEnd);
+    return toIntegerMilliseconds(timing->unloadEventEnd);
 }
     
 unsigned long long Timing::redirectStart() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
-        
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->redirectStart);
+
+    return toIntegerMilliseconds(timing->redirectStart);
 }
     
 unsigned long long Timing::redirectEnd() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
-        
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->redirectEnd);
+
+    return toIntegerMilliseconds(timing->redirectEnd);
 }
 
 unsigned long long Timing::fetchStart() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
 
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->fetchStart);
+    return toIntegerMilliseconds(timing->fetchStart);
 }
 
 unsigned long long Timing::domainLookupStart() const
@@ -113,7 +139,7 @@ unsigned long long Timing::domainLookupStart() const
     if (dnsStart < 0)
         return fetchStart();
 
-    return toIntegerMilliseconds(timing->requestTime) + dnsStart;
+    return resourceLoadTimeRelativeToAbsolute(dnsStart);
 }
 
 unsigned long long Timing::domainLookupEnd() const
@@ -128,7 +154,7 @@ unsigned long long Timing::domainLookupEnd() const
     if (dnsEnd < 0)
         return domainLookupStart();
 
-    return toIntegerMilliseconds(timing->requestTime) + dnsEnd;
+    return resourceLoadTimeRelativeToAbsolute(dnsEnd);
 }
 
 unsigned long long Timing::connectStart() const
@@ -143,7 +169,7 @@ unsigned long long Timing::connectStart() const
     if (connectStart < 0)
         return domainLookupEnd();
 
-    return toIntegerMilliseconds(timing->requestTime) + connectStart;
+    return resourceLoadTimeRelativeToAbsolute(connectStart);
 }
 
 unsigned long long Timing::connectEnd() const
@@ -158,7 +184,7 @@ unsigned long long Timing::connectEnd() const
     if (connectEnd < 0)
         return connectStart();
 
-    return toIntegerMilliseconds(timing->requestTime) + connectEnd;
+    return resourceLoadTimeRelativeToAbsolute(connectEnd);
 }
 
 unsigned long long Timing::requestStart() const
@@ -168,7 +194,7 @@ unsigned long long Timing::requestStart() const
         return 0;
 
     ASSERT(timing->sendStart >= 0);
-    return toIntegerMilliseconds(timing->requestTime) + timing->sendStart;
+    return resourceLoadTimeRelativeToAbsolute(timing->sendStart);
 }
 
 unsigned long long Timing::requestEnd() const
@@ -178,7 +204,7 @@ unsigned long long Timing::requestEnd() const
         return 0;
 
     ASSERT(timing->sendEnd >= 0);
-    return toIntegerMilliseconds(timing->requestTime) + timing->sendEnd;
+    return resourceLoadTimeRelativeToAbsolute(timing->sendEnd);
 }
 
 unsigned long long Timing::responseStart() const
@@ -194,40 +220,78 @@ unsigned long long Timing::responseStart() const
     // is basically equivalent. But for some responses, particularly those with
     // headers larger than a single packet, this time will be too late.
     ASSERT(timing->receiveHeadersEnd >= 0);
-    return toIntegerMilliseconds(timing->requestTime) + timing->receiveHeadersEnd;
+    return resourceLoadTimeRelativeToAbsolute(timing->receiveHeadersEnd);
 }
 
 unsigned long long Timing::responseEnd() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
 
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->responseEnd);
+    return toIntegerMilliseconds(timing->responseEnd);
 }
 
 unsigned long long Timing::loadEventStart() const
 {
-    if (!m_frame)
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
         return 0;
 
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->loadEventStart);
+    return toIntegerMilliseconds(timing->loadEventStart);
 }
 
 unsigned long long Timing::loadEventEnd() const
 {
+    DocumentLoadTiming* timing = documentLoadTiming();
+    if (!timing)
+        return 0;
+
+    return toIntegerMilliseconds(timing->loadEventEnd);
+}
+
+DocumentLoader* Timing::documentLoader() const
+{
     if (!m_frame)
         return 0;
 
-    return toIntegerMilliseconds(m_frame->loader()->frameLoadTimeline()->loadEventEnd);
+    return m_frame->loader()->documentLoader();
+}
+
+DocumentLoadTiming* Timing::documentLoadTiming() const
+{
+    DocumentLoader* loader = documentLoader();
+    if (!loader)
+        return 0;
+
+    return loader->timing();
 }
 
 ResourceLoadTiming* Timing::resourceLoadTiming() const
 {
-    DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
-    if (!documentLoader)
+    DocumentLoader* loader = documentLoader();
+    if (!loader)
         return 0;
 
-    return documentLoader->response().resourceLoadTiming();
+    return loader->response().resourceLoadTiming();
+}
+
+unsigned long long Timing::resourceLoadTimeRelativeToAbsolute(int relativeSeconds) const
+{
+    ASSERT(relativeSeconds >= 0);
+    ResourceLoadTiming* resourceTiming = resourceLoadTiming();
+    ASSERT(resourceTiming);
+    DocumentLoadTiming* documentTiming = documentLoadTiming();
+    ASSERT(documentTiming);
+
+    // The ResourceLoadTiming API's requestTime is the base time to which all
+    // other marks are relative. So to get an absolute time, we must add it to
+    // the relative marks.
+    //
+    // Since ResourceLoadTimings came from the network platform layer, we must
+    // check them for skew because they may be from another thread/process.
+    double baseTime = getPossiblySkewedTimeInKnownRange(resourceTiming->requestTime, documentTiming->fetchStart, documentTiming->responseEnd);
+    return toIntegerMilliseconds(baseTime) + relativeSeconds;
 }
 
 } // namespace WebCore
diff --git a/WebCore/page/Timing.h b/WebCore/page/Timing.h
index eaea633..f48f525 100644
--- a/WebCore/page/Timing.h
+++ b/WebCore/page/Timing.h
@@ -38,6 +38,8 @@
 
 namespace WebCore {
 
+struct DocumentLoadTiming;
+class DocumentLoader;
 class Frame;
 class ResourceLoadTiming;
 
@@ -67,7 +69,10 @@ public:
 private:
     Timing(Frame*);
 
+    DocumentLoader* documentLoader() const;
+    DocumentLoadTiming* documentLoadTiming() const;
     ResourceLoadTiming* resourceLoadTiming() const;
+    unsigned long long resourceLoadTimeRelativeToAbsolute(int) const;
 
     Frame* m_frame;
 };

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list