Title: [258123] trunk/Source
Revision
258123
Author
beid...@apple.com
Date
2020-03-08 17:43:28 -0700 (Sun, 08 Mar 2020)

Log Message

Remember completed subranges during incremental PDF loading.
https://bugs.webkit.org/show_bug.cgi?id=208785

Reviewed by Tim Horton.

Source/_javascript_Core:

Move 'using WTF::Range' from the WTF/Range.h header to these JSC users.

The alternative to making these 3 changes was to make over 20 changes up in the WebCore/WebKits
to resolve the conflict with WebCore::Range.

* b3/B3HeapRange.h:
* b3/air/AirAllocateRegistersAndStackByLinearScan.cpp:
* heap/JITStubRoutineSet.h:

Source/WebKit:

When a range request from a stream loader completes, we will now extend the main resource buffer
to be large enough to hold that range, then we memcpy the data into the main buffer.

We then keep a RangeSet to remember which ranges we've loaded.
Any future range request that comes in we first check against that RangeSet to see if we can handle it from memory.

This is a necessary optimization because PDFKit tends to ask for the same (or overlapping) ranges quite often.

* WebProcess/Plugins/PDF/PDFPlugin.h:
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::ByteRangeRequest::completeWithAccumulatedData):
(WebKit::PDFPlugin::ByteRangeRequest::maybeComplete):
(WebKit::PDFPlugin::pdfDocumentDidLoad):
(WebKit::PDFPlugin::manualStreamDidReceiveData):

Source/WTF:

* wtf/Range.h: Don't include the typical 'using WTF::Range' as that makes it almost impossible
  to use in the stack at WebCore or higher (Because of WebCore::Range)

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (258122 => 258123)


--- trunk/Source/_javascript_Core/ChangeLog	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-03-09 00:43:28 UTC (rev 258123)
@@ -1,3 +1,19 @@
+2020-03-08  Brady Eidson  <beid...@apple.com>
+
+        Remember completed subranges during incremental PDF loading.
+        https://bugs.webkit.org/show_bug.cgi?id=208785
+
+        Reviewed by Tim Horton.
+
+        Move 'using WTF::Range' from the WTF/Range.h header to these JSC users.
+        
+        The alternative to making these 3 changes was to make over 20 changes up in the WebCore/WebKits
+        to resolve the conflict with WebCore::Range.
+        
+        * b3/B3HeapRange.h:
+        * b3/air/AirAllocateRegistersAndStackByLinearScan.cpp:
+        * heap/JITStubRoutineSet.h:
+
 2020-03-07  Alexey Shvayka  <shvaikal...@gmail.com>
 
         REGRESSION (r258049): Unchecked JS exception in jsc::Stringifier::toJSON

Modified: trunk/Source/_javascript_Core/b3/B3HeapRange.h (258122 => 258123)


--- trunk/Source/_javascript_Core/b3/B3HeapRange.h	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/_javascript_Core/b3/B3HeapRange.h	2020-03-09 00:43:28 UTC (rev 258123)
@@ -29,6 +29,8 @@
 
 #include <wtf/Range.h>
 
+using WTF::Range;
+
 namespace JSC { namespace B3 {
 
 // Alias analysis in B3 is done by checking if two integer ranges overlap. This is powerful enough

Modified: trunk/Source/_javascript_Core/b3/air/AirAllocateRegistersAndStackByLinearScan.cpp (258122 => 258123)


--- trunk/Source/_javascript_Core/b3/air/AirAllocateRegistersAndStackByLinearScan.cpp	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/_javascript_Core/b3/air/AirAllocateRegistersAndStackByLinearScan.cpp	2020-03-09 00:43:28 UTC (rev 258123)
@@ -44,6 +44,8 @@
 #include <wtf/ListDump.h>
 #include <wtf/Range.h>
 
+using WTF::Range;
+
 namespace JSC { namespace B3 { namespace Air {
 
 namespace {

Modified: trunk/Source/_javascript_Core/heap/JITStubRoutineSet.h (258122 => 258123)


--- trunk/Source/_javascript_Core/heap/JITStubRoutineSet.h	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/_javascript_Core/heap/JITStubRoutineSet.h	2020-03-09 00:43:28 UTC (rev 258123)
@@ -31,6 +31,8 @@
 #include <wtf/Range.h>
 #include <wtf/Vector.h>
 
+using WTF::Range;
+
 namespace JSC {
 
 class GCAwareJITStubRoutine;

Modified: trunk/Source/WTF/ChangeLog (258122 => 258123)


--- trunk/Source/WTF/ChangeLog	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/WTF/ChangeLog	2020-03-09 00:43:28 UTC (rev 258123)
@@ -1,3 +1,13 @@
+2020-03-08  Brady Eidson  <beid...@apple.com>
+
+        Remember completed subranges during incremental PDF loading.
+        https://bugs.webkit.org/show_bug.cgi?id=208785
+
+        Reviewed by Tim Horton.
+
+        * wtf/Range.h: Don't include the typical 'using WTF::Range' as that makes it almost impossible
+          to use in the stack at WebCore or higher (Because of WebCore::Range)
+
 2020-03-08  Per Arne Vollan  <pvol...@apple.com>
 
         Unreviewed build fix.

Modified: trunk/Source/WTF/wtf/Range.h (258122 => 258123)


--- trunk/Source/WTF/wtf/Range.h	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/WTF/wtf/Range.h	2020-03-09 00:43:28 UTC (rev 258123)
@@ -138,6 +138,3 @@
 };
 
 } // namespace WTF
-
-using WTF::Range;
-

Modified: trunk/Source/WebKit/ChangeLog (258122 => 258123)


--- trunk/Source/WebKit/ChangeLog	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/WebKit/ChangeLog	2020-03-09 00:43:28 UTC (rev 258123)
@@ -1,3 +1,25 @@
+2020-03-08  Brady Eidson  <beid...@apple.com>
+
+        Remember completed subranges during incremental PDF loading.
+        https://bugs.webkit.org/show_bug.cgi?id=208785
+
+        Reviewed by Tim Horton.
+
+        When a range request from a stream loader completes, we will now extend the main resource buffer
+        to be large enough to hold that range, then we memcpy the data into the main buffer.
+        
+        We then keep a RangeSet to remember which ranges we've loaded.
+        Any future range request that comes in we first check against that RangeSet to see if we can handle it from memory.
+        
+        This is a necessary optimization because PDFKit tends to ask for the same (or overlapping) ranges quite often.
+        
+        * WebProcess/Plugins/PDF/PDFPlugin.h:
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::ByteRangeRequest::completeWithAccumulatedData):
+        (WebKit::PDFPlugin::ByteRangeRequest::maybeComplete):
+        (WebKit::PDFPlugin::pdfDocumentDidLoad):
+        (WebKit::PDFPlugin::manualStreamDidReceiveData):
+
 2020-02-28  Jer Noble  <jer.no...@apple.com>
 
         [GPUP] Implement Legacy EME API in the GPU Process

Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h (258122 => 258123)


--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h	2020-03-09 00:43:28 UTC (rev 258123)
@@ -38,6 +38,8 @@
 #include <WebCore/ScrollableArea.h>
 #include <wtf/HashMap.h>
 #include <wtf/Identified.h>
+#include <wtf/Range.h>
+#include <wtf/RangeSet.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/Threading.h>
 
@@ -368,6 +370,7 @@
     RefPtr<Thread> m_pdfThread;
     HashMap<uint64_t, ByteRangeRequest> m_outstandingByteRangeRequests;
     HashMap<RefPtr<WebCore::NetscapePlugInStreamLoader>, uint64_t> m_streamLoaderMap;
+    RangeSet<WTF::Range<uint64_t>> m_completedRanges;
     bool m_incrementalPDFLoadingEnabled;
 #endif
 };

Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm (258122 => 258123)


--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm	2020-03-09 00:34:40 UTC (rev 258122)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm	2020-03-09 00:43:28 UTC (rev 258123)
@@ -828,6 +828,20 @@
     
     if (m_streamLoader)
         plugin.forgetLoader(*m_streamLoader);
+
+    // Fold this data into the main data buffer so that if something in its range is requested again (which happens quite often)
+    // we do not need to hit the network layer again.
+
+    auto length = CFDataGetLength(plugin.m_data.get());
+    CFIndex targetSize = m_position + m_accumulatedData.size();
+    auto delta = targetSize - length;
+    if (delta > 0)
+        CFDataIncreaseLength(plugin.m_data.get(), delta);
+
+    if (m_accumulatedData.size()) {
+        memcpy(CFDataGetMutableBytePtr(plugin.m_data.get()) + m_position, m_accumulatedData.data(), m_accumulatedData.size());
+        plugin.m_completedRanges.add({ m_position, m_position + m_accumulatedData.size() - 1});
+    }
 }
 
 bool PDFPlugin::ByteRangeRequest::maybeComplete(PDFPlugin& plugin)
@@ -836,6 +850,12 @@
         completeWithBytes(CFDataGetBytePtr(plugin.m_data.get()) + m_position, m_count, plugin);
         return true;
     }
+
+    if (plugin.m_completedRanges.contains({ m_position, m_position + m_count - 1 })) {
+        LOG(PDF, "Completing request %llu with a previously completed range", identifier());
+        completeWithBytes(CFDataGetBytePtr(plugin.m_data.get()) + m_position, m_count, plugin);
+        return true;
+    }
     return false;
 }
 
@@ -1287,6 +1307,8 @@
 
 void PDFPlugin::pdfDocumentDidLoad()
 {
+    LOG(PDF, "PDF document finished loading with a total of %llu bytes", m_streamedBytes);
+
     addArchiveResource();
 
     m_documentFinishedLoading = true;
@@ -1396,6 +1418,10 @@
     m_streamedBytes += length;
 
 #if HAVE(INCREMENTAL_PDF_APIS)
+    // Keep our ranges-lookup-table compact by continuously updating its first range
+    // as the entire document streams in from the network.
+    m_completedRanges.add({ 0, m_streamedBytes - 1 });
+    
     if (m_incrementalPDFLoadingEnabled) {
         HashSet<uint64_t> handledRequests;
         for (auto& request : m_outstandingByteRangeRequests.values()) {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to