Commit 494fd715 authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Introduce EmitVarInt and EmitWithVarInt

Use them to encode int32 constants properly.
This reduces the generated wasm size in the unity benchmark from
21.6 MB to 16.8 MB (-22.2%).
This hopefully also translates to increased performance especially on
mobile because of lower memory usage.

R=bradnelson@chromium.org, titzer@chromium.org

Review-Url: https://codereview.chromium.org/2692943002
Cr-Commit-Position: refs/heads/master@{#43200}
parent 2f8ad11f
......@@ -683,35 +683,26 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
if (type->IsA(AsmType::Signed())) {
int32_t i = 0;
if (!value->ToInt32(&i)) {
UNREACHABLE();
}
byte code[] = {WASM_I32V(i)};
current_function_builder_->EmitCode(code, sizeof(code));
CHECK(value->ToInt32(&i));
current_function_builder_->EmitI32Const(i);
} else if (type->IsA(AsmType::Unsigned()) || type->IsA(AsmType::FixNum())) {
uint32_t u = 0;
if (!value->ToUint32(&u)) {
UNREACHABLE();
}
int32_t i = static_cast<int32_t>(u);
byte code[] = {WASM_I32V(i)};
current_function_builder_->EmitCode(code, sizeof(code));
CHECK(value->ToUint32(&u));
current_function_builder_->EmitI32Const(bit_cast<int32_t>(u));
} else if (type->IsA(AsmType::Int())) {
// The parser can collapse !0, !1 etc to true / false.
// Allow these as int literals.
if (expr->raw_value()->IsTrue()) {
byte code[] = {WASM_I32V(1)};
byte code[] = {WASM_ONE};
current_function_builder_->EmitCode(code, sizeof(code));
} else if (expr->raw_value()->IsFalse()) {
byte code[] = {WASM_I32V(0)};
byte code[] = {WASM_ZERO};
current_function_builder_->EmitCode(code, sizeof(code));
} else if (expr->raw_value()->IsNumber()) {
// This can happen when -x becomes x * -1 (due to the parser).
int32_t i = 0;
if (!value->ToInt32(&i) || i != -1) {
UNREACHABLE();
}
byte code[] = {WASM_I32V(i)};
CHECK(value->ToInt32(&i) && i == -1);
byte code[] = {WASM_I32V_1(-1)};
current_function_builder_->EmitCode(code, sizeof(code));
} else {
UNREACHABLE();
......
......@@ -62,13 +62,20 @@ WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder)
direct_calls_(builder->zone()),
asm_offsets_(builder->zone(), 8) {}
void WasmFunctionBuilder::EmitVarInt(int32_t val) {
byte buffer[5];
byte* ptr = buffer;
LEBHelper::write_i32v(&ptr, val);
DCHECK_GE(5, ptr - buffer);
body_.insert(body_.end(), buffer, ptr);
}
void WasmFunctionBuilder::EmitVarUint(uint32_t val) {
byte buffer[8];
byte buffer[5];
byte* ptr = buffer;
LEBHelper::write_u32v(&ptr, val);
for (byte* p = buffer; p < ptr; p++) {
body_.push_back(*p);
}
DCHECK_GE(5, ptr - buffer);
body_.insert(body_.end(), buffer, ptr);
}
void WasmFunctionBuilder::SetSignature(FunctionSig* sig) {
......@@ -116,6 +123,11 @@ void WasmFunctionBuilder::EmitWithU8U8(WasmOpcode opcode, const byte imm1,
body_.push_back(imm2);
}
void WasmFunctionBuilder::EmitWithVarInt(WasmOpcode opcode, int32_t immediate) {
body_.push_back(static_cast<byte>(opcode));
EmitVarInt(immediate);
}
void WasmFunctionBuilder::EmitWithVarUint(WasmOpcode opcode,
uint32_t immediate) {
body_.push_back(static_cast<byte>(opcode));
......@@ -123,13 +135,7 @@ void WasmFunctionBuilder::EmitWithVarUint(WasmOpcode opcode,
}
void WasmFunctionBuilder::EmitI32Const(int32_t value) {
if (-64 <= value && value <= 63) {
EmitWithU8(kExprI32Const, static_cast<byte>(value & 0x7F));
} else {
// TODO(titzer): variable-length signed and unsigned i32 constants.
byte code[] = {WASM_I32V_5(value)};
EmitCode(code, sizeof(code));
}
EmitWithVarInt(kExprI32Const, value);
}
void WasmFunctionBuilder::EmitDirectCallIndex(uint32_t index) {
......
......@@ -121,6 +121,7 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
// Building methods.
void SetSignature(FunctionSig* sig);
uint32_t AddLocal(ValueType type);
void EmitVarInt(int32_t val);
void EmitVarUint(uint32_t val);
void EmitCode(const byte* code, uint32_t code_size);
void Emit(WasmOpcode opcode);
......@@ -130,6 +131,7 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
void EmitI32Const(int32_t val);
void EmitWithU8(WasmOpcode opcode, const byte immediate);
void EmitWithU8U8(WasmOpcode opcode, const byte imm1, const byte imm2);
void EmitWithVarInt(WasmOpcode opcode, int32_t immediate);
void EmitWithVarUint(WasmOpcode opcode, uint32_t immediate);
void EmitDirectCallIndex(uint32_t index);
void ExportAs(Vector<const char> name);
......
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