Commit cc02e743 authored by mtrofin's avatar mtrofin Committed by Commit bot

[wasm] Avoid copying when deserializing wasm

Updated the deserialization API to avoid copying uncompiled
bytes.

BUG=

Review-Url: https://codereview.chromium.org/2404673002
Cr-Commit-Position: refs/heads/master@{#40108}
parent 520d33d5
......@@ -3902,6 +3902,7 @@ class V8_EXPORT Proxy : public Object {
class V8_EXPORT WasmCompiledModule : public Object {
public:
typedef std::pair<std::unique_ptr<const uint8_t[]>, size_t> SerializedModule;
typedef std::pair<std::unique_ptr<const uint8_t[]>, size_t> UncompiledBytes;
// Get the uncompiled bytes that were used to compile this module.
Local<String> GetUncompiledBytes();
......@@ -3917,12 +3918,13 @@ class V8_EXPORT WasmCompiledModule : public Object {
// uncompiled bytes.
static MaybeLocal<WasmCompiledModule> DeserializeOrCompile(
Isolate* isolate, const SerializedModule& serialized_data,
Local<String> uncompiled_bytes);
const UncompiledBytes& uncompiled_bytes);
V8_INLINE static WasmCompiledModule* Cast(Value* obj);
private:
static MaybeLocal<WasmCompiledModule> Compile(Isolate* isolate,
Local<String> bytes);
const uint8_t* start,
size_t length);
WasmCompiledModule();
static void CheckCast(Value* obj);
};
......
......@@ -7234,27 +7234,22 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
MaybeLocal<WasmCompiledModule> WasmCompiledModule::DeserializeOrCompile(
Isolate* isolate,
const WasmCompiledModule::SerializedModule& serialized_data,
Local<String> uncompiled_bytes) {
const WasmCompiledModule::UncompiledBytes& uncompiled_bytes) {
MaybeLocal<WasmCompiledModule> ret = Deserialize(isolate, serialized_data);
if (!ret.IsEmpty()) return ret;
return Compile(isolate, uncompiled_bytes);
return Compile(isolate, uncompiled_bytes.first.get(),
uncompiled_bytes.second);
}
MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(
Isolate* isolate, Local<String> bytes) {
i::Handle<i::String> module_bytes = Utils::OpenHandle(*bytes);
MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
const uint8_t* start,
size_t length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Deserialize()");
i::SeqOneByteString* data = i::SeqOneByteString::cast(*module_bytes);
// Copy bytes such that GC can not move it during construction of the module.
// TODO(wasm): Avoid this additional copy.
i::ScopedVector<unsigned char> bytes_copy(data->length());
memcpy(bytes_copy.start(), data->GetChars(), data->length());
i::MaybeHandle<i::JSObject> maybe_compiled =
i::wasm::CreateModuleObjectFromBytes(
i_isolate, bytes_copy.start(),
bytes_copy.start() + bytes_copy.length(), &thrower,
i::wasm::ModuleOrigin::kWasmOrigin);
i::wasm::CreateModuleObjectFromBytes(i_isolate, start, start + length,
&thrower,
i::wasm::ModuleOrigin::kWasmOrigin);
if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
return Local<WasmCompiledModule>::Cast(
Utils::ToLocal(maybe_compiled.ToHandleChecked()));
......
......@@ -198,7 +198,7 @@ TEST(Run_WasmModule_Serialization) {
Isolate* isolate = CcTest::InitIsolateOnce();
ErrorThrower thrower(isolate, "");
uint8_t* bytes = nullptr;
int buffer_size = -1;
size_t bytes_size = 0;
v8::WasmCompiledModule::SerializedModule data;
{
HandleScope scope(isolate);
......@@ -221,12 +221,16 @@ TEST(Run_WasmModule_Serialization) {
v8_module_obj.As<v8::WasmCompiledModule>();
v8::Local<v8::String> uncompiled_bytes =
v8_compiled_module->GetUncompiledBytes();
buffer_size = uncompiled_bytes->Length();
bytes = zone.NewArray<uint8_t>(buffer_size);
bytes_size = static_cast<size_t>(uncompiled_bytes->Length());
bytes = zone.NewArray<uint8_t>(uncompiled_bytes->Length());
uncompiled_bytes->WriteOneByte(bytes);
data = v8_compiled_module->Serialize();
}
v8::WasmCompiledModule::UncompiledBytes uncompressed_bytes = {
std::unique_ptr<const uint8_t[]>(const_cast<const uint8_t*>(bytes)),
bytes_size};
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
CcTest::InitIsolateOnce()->array_buffer_allocator();
......@@ -245,13 +249,9 @@ TEST(Run_WasmModule_Serialization) {
new_ctx->Enter();
isolate = reinterpret_cast<Isolate*>(v8_isolate);
testing::SetupIsolateForWasmModule(isolate);
Vector<const uint8_t> raw(bytes, buffer_size);
v8::MaybeLocal<v8::WasmCompiledModule> deserialized =
v8::WasmCompiledModule::DeserializeOrCompile(
v8_isolate, data,
v8::Utils::ToLocal(isolate->factory()
->NewStringFromOneByte(raw)
.ToHandleChecked()));
v8::WasmCompiledModule::DeserializeOrCompile(v8_isolate, data,
uncompressed_bytes);
v8::Local<v8::WasmCompiledModule> compiled_module;
CHECK(deserialized.ToLocal(&compiled_module));
Handle<JSObject> module_object =
......@@ -270,6 +270,9 @@ TEST(Run_WasmModule_Serialization) {
}
v8_isolate->Dispose();
}
// Release, because we allocated the bytes with the zone allocator, and
// that doesn't have a delete.
uncompressed_bytes.first.release();
}
TEST(MemorySize) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment