[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:
Mircea Trofin 2017-07-21 09:05:38 -07:00 committed by Commit Bot
parent 00681326a3
commit d77e98e8df
2 changed files with 75 additions and 0 deletions

View File

@ -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) {}

View File

@ -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]);