[wasm] Use async compilation in streaming API
This change gets the streaming compile APIs closer to their final shape, by moving to a promise-based design. Bug: chromium:747396 Bug: v8:6619 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: Ifd22ff83c79391a0f2a8ec2e5af39f71df1ea1c2 Reviewed-on: https://chromium-review.googlesource.com/581412 Commit-Queue: Brad Nelson <bradnelson@chromium.org> Reviewed-by: Brad Nelson <bradnelson@chromium.org> Cr-Commit-Position: refs/heads/master@{#46821}
This commit is contained in:
parent
00681326a3
commit
d77e98e8df
42
include/v8.h
42
include/v8.h
@ -139,6 +139,7 @@ template<typename T> class ReturnValue;
|
||||
|
||||
namespace internal {
|
||||
class Arguments;
|
||||
class DeferredHandles;
|
||||
class Heap;
|
||||
class HeapObject;
|
||||
class Isolate;
|
||||
@ -4159,6 +4160,47 @@ class V8_EXPORT WasmCompiledModule : public Object {
|
||||
static void CheckCast(Value* obj);
|
||||
};
|
||||
|
||||
// TODO(mtrofin): when streaming compilation is done, we can rename this
|
||||
// to simply WasmModuleObjectBuilder
|
||||
class V8_EXPORT WasmModuleObjectBuilderStreaming final {
|
||||
public:
|
||||
WasmModuleObjectBuilderStreaming(Isolate* isolate, Local<Promise> promise);
|
||||
// The buffer passed into OnBytesReceived is owned by the caller.
|
||||
void OnBytesReceived(const uint8_t*, size_t size);
|
||||
void Finish();
|
||||
// Currently, we don't need an explicit Abort, because there's no
|
||||
// activity happening until Finish is called. Should the connection
|
||||
// be dropped, for example, the network layer is expected to reject
|
||||
// the promise and then this object is destroyed, which, at the moment,
|
||||
// just means the {received_buffers_} are freed.
|
||||
|
||||
private:
|
||||
typedef std::pair<std::unique_ptr<const uint8_t[]>, size_t> Buffer;
|
||||
|
||||
WasmModuleObjectBuilderStreaming(const WasmModuleObjectBuilderStreaming&) =
|
||||
delete;
|
||||
WasmModuleObjectBuilderStreaming(WasmModuleObjectBuilderStreaming&&) =
|
||||
default;
|
||||
WasmModuleObjectBuilderStreaming& operator=(
|
||||
const WasmModuleObjectBuilderStreaming&) = delete;
|
||||
WasmModuleObjectBuilderStreaming& operator=(
|
||||
WasmModuleObjectBuilderStreaming&&) = default;
|
||||
Isolate* isolate_ = nullptr;
|
||||
|
||||
#if V8_CC_MSVC
|
||||
// We don't need the static Copy API, so the default
|
||||
// NonCopyablePersistentTraits would be sufficient, however,
|
||||
// MSVC eagerly instantiates the Copy.
|
||||
// We ensure we don't use Copy, however, by compiling with the
|
||||
// defaults everywhere else.
|
||||
Persistent<Promise, CopyablePersistentTraits<Promise>> promise_;
|
||||
#else
|
||||
Persistent<Promise> promise_;
|
||||
#endif
|
||||
std::vector<Buffer> received_buffers_;
|
||||
size_t total_size_ = 0;
|
||||
};
|
||||
|
||||
class V8_EXPORT WasmModuleObjectBuilder final {
|
||||
public:
|
||||
WasmModuleObjectBuilder(Isolate* isolate) : isolate_(isolate) {}
|
||||
|
33
src/api.cc
33
src/api.cc
@ -7813,6 +7813,39 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
|
||||
Utils::ToLocal(maybe_compiled.ToHandleChecked()));
|
||||
}
|
||||
|
||||
WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
|
||||
Isolate* isolate, Local<Promise> promise)
|
||||
: isolate_(isolate) {
|
||||
promise_.Reset(isolate, promise);
|
||||
}
|
||||
|
||||
void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
|
||||
size_t size) {
|
||||
std::unique_ptr<uint8_t[]> cloned_bytes(new uint8_t[size]);
|
||||
memcpy(cloned_bytes.get(), bytes, size);
|
||||
received_buffers_.push_back(
|
||||
Buffer(std::unique_ptr<const uint8_t[]>(
|
||||
const_cast<const uint8_t*>(cloned_bytes.release())),
|
||||
size));
|
||||
total_size_ += size;
|
||||
}
|
||||
|
||||
void WasmModuleObjectBuilderStreaming::Finish() {
|
||||
std::unique_ptr<uint8_t[]> wire_bytes(new uint8_t[total_size_]);
|
||||
uint8_t* insert_at = wire_bytes.get();
|
||||
|
||||
for (size_t i = 0; i < received_buffers_.size(); ++i) {
|
||||
const Buffer& buff = received_buffers_[i];
|
||||
memcpy(insert_at, buff.first.get(), buff.second);
|
||||
insert_at += buff.second;
|
||||
}
|
||||
// AsyncCompile makes its own copy of the wire bytes. This inefficiency
|
||||
// will be resolved when we move to true streaming compilation.
|
||||
i::wasm::AsyncCompile(reinterpret_cast<i::Isolate*>(isolate_),
|
||||
Utils::OpenHandle(*promise_.Get(isolate_)),
|
||||
{wire_bytes.get(), wire_bytes.get() + total_size_});
|
||||
}
|
||||
|
||||
void WasmModuleObjectBuilder::OnBytesReceived(const uint8_t* bytes,
|
||||
size_t size) {
|
||||
std::unique_ptr<uint8_t[]> cloned_bytes(new uint8_t[size]);
|
||||
|
Loading…
Reference in New Issue
Block a user