From 61c9683d712e5f168b34ca79d6e94a10bb30e59f Mon Sep 17 00:00:00 2001 From: "marja@chromium.org" Date: Thu, 11 Sep 2014 11:06:26 +0000 Subject: [PATCH] Add script streaming API. Blink will use this API to stream script data into V8 as the scripts load. During loading, V8 can already parse the scripts. They will be then compiled and executed when the loading is complete. BUG= R=jochen@chromium.org, rossberg@chromium.org, svenpanne@chromium.org, yangguo@chromium.org Review URL: https://codereview.chromium.org/366153002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23865 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- BUILD.gn | 2 + include/v8.h | 94 ++++++++++++ src/api.cc | 98 +++++++++++++ src/background-parsing-task.cc | 62 ++++++++ src/background-parsing-task.h | 67 +++++++++ src/compiler.cc | 95 ++++++++---- src/compiler.h | 23 +++ src/parser.cc | 100 +++++++++---- src/parser.h | 16 ++- src/scanner-character-streams.cc | 182 ++++++++++++++++++++--- src/scanner-character-streams.h | 43 ++++++ test/cctest/test-api.cc | 304 +++++++++++++++++++++++++++++++++++++++ tools/gyp/v8.gyp | 2 + 13 files changed, 1010 insertions(+), 78 deletions(-) create mode 100644 src/background-parsing-task.cc create mode 100644 src/background-parsing-task.h diff --git a/BUILD.gn b/BUILD.gn index 76d48d1..b5e56e5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -435,6 +435,8 @@ source_set("v8_base") { "src/ast-value-factory.h", "src/ast.cc", "src/ast.h", + "src/background-parsing-task.cc", + "src/background-parsing-task.h", "src/bignum-dtoa.cc", "src/bignum-dtoa.h", "src/bignum.cc", diff --git a/include/v8.h b/include/v8.h index d6fbf67..19b2778 100644 --- a/include/v8.h +++ b/include/v8.h @@ -130,6 +130,7 @@ class Heap; class HeapObject; class Isolate; class Object; +class StreamedSource; template class CustomArguments; class PropertyCallbackArguments; class FunctionCallbackArguments; @@ -1088,6 +1089,73 @@ class V8_EXPORT ScriptCompiler { CachedData* cached_data; }; + /** + * For streaming incomplete script data to V8. The embedder should implement a + * subclass of this class. + */ + class ExternalSourceStream { + public: + virtual ~ExternalSourceStream() {} + + /** + * V8 calls this to request the next chunk of data from the embedder. This + * function will be called on a background thread, so it's OK to block and + * wait for the data, if the embedder doesn't have data yet. Returns the + * length of the data returned. When the data ends, GetMoreData should + * return 0. Caller takes ownership of the data. + * + * When streaming UTF-8 data, V8 handles multi-byte characters split between + * two data chunks, but doesn't handle multi-byte characters split between + * more than two data chunks. The embedder can avoid this problem by always + * returning at least 2 bytes of data. + * + * If the embedder wants to cancel the streaming, they should make the next + * GetMoreData call return 0. V8 will interpret it as end of data (and most + * probably, parsing will fail). The streaming task will return as soon as + * V8 has parsed the data it received so far. + */ + virtual size_t GetMoreData(const uint8_t** src) = 0; + }; + + + /** + * Source code which can be streamed into V8 in pieces. It will be parsed + * while streaming. It can be compiled after the streaming is complete. + * StreamedSource must be kept alive while the streaming task is ran (see + * ScriptStreamingTask below). + */ + class V8_EXPORT StreamedSource { + public: + enum Encoding { ONE_BYTE, TWO_BYTE, UTF8 }; + + StreamedSource(ExternalSourceStream* source_stream, Encoding encoding); + ~StreamedSource(); + + // Ownership of the CachedData or its buffers is *not* transferred to the + // caller. The CachedData object is alive as long as the StreamedSource + // object is alive. + const CachedData* GetCachedData() const; + + internal::StreamedSource* impl() const { return impl_; } + + private: + // Prevent copying. Not implemented. + StreamedSource(const StreamedSource&); + StreamedSource& operator=(const StreamedSource&); + + internal::StreamedSource* impl_; + }; + + /** + * A streaming task which the embedder must run on a background thread to + * stream scripts into V8. Returned by ScriptCompiler::StartStreamingScript. + */ + class ScriptStreamingTask { + public: + virtual ~ScriptStreamingTask() {} + virtual void Run() = 0; + }; + enum CompileOptions { kNoCompileOptions = 0, kProduceParserCache, @@ -1130,6 +1198,32 @@ class V8_EXPORT ScriptCompiler { static Local