Title: [288463] trunk/Source/WebCore
Revision
288463
Author
you...@apple.com
Date
2022-01-24 13:12:37 -0800 (Mon, 24 Jan 2022)

Log Message

file.stream() is slow and CPU-bound
https://bugs.webkit.org/show_bug.cgi?id=235448

Reviewed by Alex Christensen.

We introduce a ReadAsBinaryChunks mode to prevent storing the whole file in memory.
Use this in Blob stream implementation.
The new implementation is much faster for big files given it does not need to keep in memory the whole file.
Covered by existing tests.

* fileapi/Blob.cpp:
* fileapi/FileReaderLoader.cpp:
* fileapi/FileReaderLoader.h:
* fileapi/FileReaderLoaderClient.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (288462 => 288463)


--- trunk/Source/WebCore/ChangeLog	2022-01-24 21:11:01 UTC (rev 288462)
+++ trunk/Source/WebCore/ChangeLog	2022-01-24 21:12:37 UTC (rev 288463)
@@ -1,5 +1,22 @@
 2022-01-24  Youenn Fablet  <you...@apple.com>
 
+        file.stream() is slow and CPU-bound
+        https://bugs.webkit.org/show_bug.cgi?id=235448
+
+        Reviewed by Alex Christensen.
+
+        We introduce a ReadAsBinaryChunks mode to prevent storing the whole file in memory.
+        Use this in Blob stream implementation.
+        The new implementation is much faster for big files given it does not need to keep in memory the whole file.
+        Covered by existing tests.
+
+        * fileapi/Blob.cpp:
+        * fileapi/FileReaderLoader.cpp:
+        * fileapi/FileReaderLoader.h:
+        * fileapi/FileReaderLoaderClient.h:
+
+2022-01-24  Youenn Fablet  <you...@apple.com>
+
         [ iOS Release ] fast/mediastream/mediaElement-gc.html is a flaky failure
         https://bugs.webkit.org/show_bug.cgi?id=231601
         <rdar://problem/84158942>

Modified: trunk/Source/WebCore/fileapi/Blob.cpp (288462 => 288463)


--- trunk/Source/WebCore/fileapi/Blob.cpp	2022-01-24 21:11:01 UTC (rev 288462)
+++ trunk/Source/WebCore/fileapi/Blob.cpp	2022-01-24 21:12:37 UTC (rev 288463)
@@ -241,7 +241,7 @@
     class BlobStreamSource : public FileReaderLoaderClient, public ReadableStreamSource {
     public:
         BlobStreamSource(ScriptExecutionContext& scriptExecutionContext, Blob& blob)
-            : m_loader(makeUniqueRef<FileReaderLoader>(FileReaderLoader::ReadType::ReadAsArrayBuffer, this))
+            : m_loader(makeUniqueRef<FileReaderLoader>(FileReaderLoader::ReadType::ReadAsBinaryChunks, this))
         {
             m_loader->start(&scriptExecutionContext, blob);
         }
@@ -265,19 +265,11 @@
 
         // FileReaderLoaderClient
         void didStartLoading() final { }
-        void didReceiveData() final
+        void didReceiveData() final { }
+        void didReceiveBinaryChunk(const SharedBuffer& buffer) final
         {
-            auto result = m_loader->arrayBufferResult();
-            if (!result)
-                return;
-
-            if (m_loader->isCompleted() && !m_bytesRead)
-                controller().enqueue(WTFMove(result));
-            else {
-                auto bytesLoaded = m_loader->bytesLoaded();
-                controller().enqueue(result->slice(m_bytesRead, bytesLoaded));
-                m_bytesRead = bytesLoaded;
-            }
+            if (!controller().enqueue(buffer.tryCreateArrayBuffer()))
+                doCancel();
         }
         void didFinishLoading() final
         {
@@ -294,7 +286,6 @@
         }
 
         UniqueRef<FileReaderLoader> m_loader;
-        size_t m_bytesRead { 0 };
         bool m_isStarted { false };
         std::optional<Exception> m_exception;
     };

Modified: trunk/Source/WebCore/fileapi/FileReaderLoader.cpp (288462 => 288463)


--- trunk/Source/WebCore/fileapi/FileReaderLoader.cpp	2022-01-24 21:11:01 UTC (rev 288462)
+++ trunk/Source/WebCore/fileapi/FileReaderLoader.cpp	2022-01-24 21:12:37 UTC (rev 288463)
@@ -177,6 +177,12 @@
     if (m_errorCode)
         return;
 
+    if (m_readType == ReadType::ReadAsBinaryChunks) {
+        if (m_client)
+            m_client->didReceiveBinaryChunk(buffer);
+        return;
+    }
+
     int length = buffer.size();
     unsigned remainingBufferSpace = m_totalBytes - m_bytesLoaded;
     if (length > static_cast<long long>(remainingBufferSpace)) {
@@ -311,7 +317,8 @@
         if (isCompleted())
             convertToDataURL();
         break;
-    default:
+    case ReadAsBlob:
+    case ReadAsBinaryChunks:
         ASSERT_NOT_REACHED();
     }
     

Modified: trunk/Source/WebCore/fileapi/FileReaderLoader.h (288462 => 288463)


--- trunk/Source/WebCore/fileapi/FileReaderLoader.h	2022-01-24 21:11:01 UTC (rev 288462)
+++ trunk/Source/WebCore/fileapi/FileReaderLoader.h	2022-01-24 21:12:37 UTC (rev 288463)
@@ -58,7 +58,8 @@
         ReadAsBinaryString,
         ReadAsBlob,
         ReadAsText,
-        ReadAsDataURL
+        ReadAsDataURL,
+        ReadAsBinaryChunks
     };
 
     // If client is given, do the loading asynchronously. Otherwise, load synchronously.

Modified: trunk/Source/WebCore/fileapi/FileReaderLoaderClient.h (288462 => 288463)


--- trunk/Source/WebCore/fileapi/FileReaderLoaderClient.h	2022-01-24 21:11:01 UTC (rev 288462)
+++ trunk/Source/WebCore/fileapi/FileReaderLoaderClient.h	2022-01-24 21:12:37 UTC (rev 288463)
@@ -41,6 +41,7 @@
 
     virtual void didStartLoading() = 0;
     virtual void didReceiveData() = 0;
+    virtual void didReceiveBinaryChunk(const SharedBuffer&) { }
     virtual void didFinishLoading() = 0;
     virtual void didFail(ExceptionCode errorCode) = 0;
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to