Commit e27deb72 authored by Stephan Herhut's avatar Stephan Herhut Committed by Commit Bot

[wasm] Load module name during streaming compile

The streaming compilation pipeline did not parse the names section and
this is also not longer needed for getting function or local names.
However, the module name still needs to be set eagerly.

Change-Id: I1ac12e98b970ea0781302dc44ee684510bdf2d69
Reviewed-on: https://chromium-review.googlesource.com/962452Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Stephan Herhut <herhut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51979}
parent 4ae31dab
...@@ -46,6 +46,8 @@ class Decoder { ...@@ -46,6 +46,8 @@ class Decoder {
Decoder(const byte* start, const byte* end, uint32_t buffer_offset = 0) Decoder(const byte* start, const byte* end, uint32_t buffer_offset = 0)
: Decoder(start, start, end, buffer_offset) {} : Decoder(start, start, end, buffer_offset) {}
explicit Decoder(const Vector<const byte> bytes, uint32_t buffer_offset = 0)
: Decoder(bytes.start(), bytes.start() + bytes.length(), buffer_offset) {}
Decoder(const byte* start, const byte* pc, const byte* end, Decoder(const byte* start, const byte* pc, const byte* end,
uint32_t buffer_offset = 0) uint32_t buffer_offset = 0)
: start_(start), pc_(pc), end_(end), buffer_offset_(buffer_offset) { : start_(start), pc_(pc), end_(end), buffer_offset_(buffer_offset) {
...@@ -248,6 +250,7 @@ class Decoder { ...@@ -248,6 +250,7 @@ class Decoder {
const byte* start() const { return start_; } const byte* start() const { return start_; }
const byte* pc() const { return pc_; } const byte* pc() const { return pc_; }
uint32_t position() const { return static_cast<uint32_t>(pc_ - start_); }
uint32_t pc_offset() const { uint32_t pc_offset() const {
return static_cast<uint32_t>(pc_ - start_) + buffer_offset_; return static_cast<uint32_t>(pc_ - start_) + buffer_offset_;
} }
......
...@@ -3262,18 +3262,23 @@ bool AsyncStreamingProcessor::ProcessSection(SectionCode section_code, ...@@ -3262,18 +3262,23 @@ bool AsyncStreamingProcessor::ProcessSection(SectionCode section_code,
uint32_t offset) { uint32_t offset) {
TRACE_STREAMING("Process section %d ...\n", section_code); TRACE_STREAMING("Process section %d ...\n", section_code);
if (compilation_unit_builder_) { if (compilation_unit_builder_) {
// We reached a section after the code section, we do not need the the // We reached a section after the code section, we do not need the
// compilation_unit_builder_ anymore. // compilation_unit_builder_ anymore.
CommitCompilationUnits(); CommitCompilationUnits();
compilation_unit_builder_.reset(); compilation_unit_builder_.reset();
} }
if (section_code == SectionCode::kUnknownSectionCode) { if (section_code == SectionCode::kUnknownSectionCode) {
// No need to decode unknown sections, even the names section. If decoding Decoder decoder(bytes, offset);
// of the unknown section fails, compilation should succeed anyways, and section_code = ModuleDecoder::IdentifyUnknownSection(
// even decoding the names section is unnecessary because the result comes decoder, bytes.start() + bytes.length());
// too late for streaming compilation. if (section_code == SectionCode::kUnknownSectionCode) {
// Skip unknown sections that we do not know how to handle.
return true; return true;
} }
// Remove the unknown section tag from the payload bytes.
offset += decoder.position();
bytes = bytes.SubVector(decoder.position(), bytes.size());
}
constexpr bool verify_functions = false; constexpr bool verify_functions = false;
decoder_.DecodeSection(section_code, bytes, offset, verify_functions); decoder_.DecodeSection(section_code, bytes, offset, verify_functions);
if (!decoder_.ok()) { if (!decoder_.ok()) {
......
...@@ -218,25 +218,11 @@ class WasmSectionIterator { ...@@ -218,25 +218,11 @@ class WasmSectionIterator {
if (section_code == kUnknownSectionCode) { if (section_code == kUnknownSectionCode) {
// Check for the known "name" section. // Check for the known "name" section.
WireBytesRef string = section_code =
wasm::consume_string(decoder_, true, "section name"); ModuleDecoder::IdentifyUnknownSection(decoder_, section_end_);
if (decoder_.failed() || decoder_.pc() > section_end_) { // As a side effect, the above function will forward the decoder to after
section_code_ = kUnknownSectionCode; // the identifier string.
return;
}
const byte* section_name_start =
decoder_.start() + decoder_.GetBufferRelativeOffset(string.offset());
payload_start_ = decoder_.pc(); payload_start_ = decoder_.pc();
TRACE(" +%d section name : \"%.*s\"\n",
static_cast<int>(section_name_start - decoder_.start()),
string.length() < 20 ? string.length() : 20, section_name_start);
if (string.length() == num_chars(kNameString) &&
strncmp(reinterpret_cast<const char*>(section_name_start),
kNameString, num_chars(kNameString)) == 0) {
section_code = kNameSectionCode;
}
} else if (!IsValidSectionCode(section_code)) { } else if (!IsValidSectionCode(section_code)) {
decoder_.errorf(decoder_.pc(), "unknown section code #0x%02x", decoder_.errorf(decoder_.pc(), "unknown section code #0x%02x",
section_code); section_code);
...@@ -1392,6 +1378,27 @@ ModuleResult ModuleDecoder::FinishDecoding(bool verify_functions) { ...@@ -1392,6 +1378,27 @@ ModuleResult ModuleDecoder::FinishDecoding(bool verify_functions) {
return impl_->FinishDecoding(verify_functions); return impl_->FinishDecoding(verify_functions);
} }
SectionCode ModuleDecoder::IdentifyUnknownSection(Decoder& decoder,
const byte* end) {
WireBytesRef string = wasm::consume_string(decoder, true, "section name");
if (decoder.failed() || decoder.pc() > end) {
return kUnknownSectionCode;
}
const byte* section_name_start =
decoder.start() + decoder.GetBufferRelativeOffset(string.offset());
TRACE(" +%d section name : \"%.*s\"\n",
static_cast<int>(section_name_start - decoder.start()),
string.length() < 20 ? string.length() : 20, section_name_start);
if (string.length() == num_chars(kNameString) &&
strncmp(reinterpret_cast<const char*>(section_name_start), kNameString,
num_chars(kNameString)) == 0) {
return kNameSectionCode;
}
return kUnknownSectionCode;
}
bool ModuleDecoder::ok() { return impl_->ok(); } bool ModuleDecoder::ok() { return impl_->ok(); }
ModuleResult SyncDecodeWasmModule(Isolate* isolate, const byte* module_start, ModuleResult SyncDecodeWasmModule(Isolate* isolate, const byte* module_start,
......
...@@ -146,6 +146,16 @@ class ModuleDecoder { ...@@ -146,6 +146,16 @@ class ModuleDecoder {
bool ok(); bool ok();
// Translates the unknown section that decoder is pointing to to an extended
// SectionCode if the unknown section is known to decoder. Currently this only
// handles the name section.
// The decoder is expected to point after the section lenght and just before
// the identifier string of the unknown section.
// If a SectionCode other than kUnknownSectionCode is returned, the decoder
// will point right after the identifier string. Otherwise, the position is
// undefined.
static SectionCode IdentifyUnknownSection(Decoder& decoder, const byte* end);
private: private:
std::unique_ptr<ModuleDecoderImpl> impl_; std::unique_ptr<ModuleDecoderImpl> impl_;
}; };
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --no-stress-opt
load('test/mjsunit/mjsunit.js');
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_v).addBody([kExprUnreachable]).exportFunc();
let buffer = builder.toBuffer();
assertPromiseResult(WebAssembly.instantiate(buffer), pair => {
try {
pair.instance.exports.main();
} catch (e) {
print(e.stack);
}
});
RuntimeError: unreachable
at main (wasm-function[0]:1)
at pair (*%(basename)s:16:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --wasm-test-streaming --no-stress-opt
load("test/message/wasm-function-name-async.js");
RuntimeError: unreachable
at main (wasm-function[0]:1)
at pair (test/message/wasm-function-name-async.js:16:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --no-stress-opt
load('test/mjsunit/mjsunit.js');
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder();
builder.setName('test-module');
builder.addFunction('main', kSig_i_v).addBody([kExprUnreachable]).exportFunc();
let buffer = builder.toBuffer();
assertPromiseResult(WebAssembly.instantiate(buffer), pair => {
try {
pair.instance.exports.main();
} catch (e) {
print(e.stack);
}
});
RuntimeError: unreachable
at test-module.main (wasm-function[0]:1)
at pair (*%(basename)s:17:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --wasm-test-streaming --no-stress-opt
load("test/message/wasm-module-and-function-name-async.js");
RuntimeError: unreachable
at test-module.main (wasm-function[0]:1)
at pair (test/message/wasm-module-and-function-name-async.js:17:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --no-stress-opt
load('test/mjsunit/mjsunit.js');
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder();
builder.setName('test-module');
builder.addFunction(undefined, kSig_i_v)
.addBody([kExprUnreachable])
.exportAs('main');
let buffer = builder.toBuffer();
assertPromiseResult(WebAssembly.instantiate(buffer), pair => {
try {
pair.instance.exports.main();
} catch (e) {
print(e.stack);
}
});
RuntimeError: unreachable
at test-module (wasm-function[0]:1)
at pair (*%(basename)s:19:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --wasm-test-streaming --no-stress-opt
load("test/message/wasm-module-name-async.js");
RuntimeError: unreachable
at test-module (wasm-function[0]:1)
at pair (test/message/wasm-module-name-async.js:19:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --no-stress-opt
load('test/mjsunit/mjsunit.js');
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_v)
.addBody([kExprUnreachable])
.exportAs('main');
let buffer = builder.toBuffer();
assertPromiseResult(WebAssembly.instantiate(buffer), pair => {
try {
pair.instance.exports.main();
} catch (e) {
print(e.stack);
}
});
RuntimeError: unreachable
at wasm-function[0]:1
at pair (*%(basename)s:18:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --wasm-test-streaming --no-stress-opt
load("test/message/wasm-no-name-async.js");
RuntimeError: unreachable
at wasm-function[0]:1
at pair (test/message/wasm-no-name-async.js:18:27)
at promise.then.result (test/mjsunit/mjsunit.js:576:15)
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