mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1929342 - Inline wasm:js-string length. r=rhunt
Differential Revision: https://phabricator.services.mozilla.com/D228071
This commit is contained in:
parent
b98dc1b8e2
commit
0cf5041bfe
@ -22018,6 +22018,19 @@ void CodeGenerator::visitWasmTrapIfAnyRefIsNotJSString(
|
|||||||
masm.bind(&isJSString);
|
masm.bind(&isJSString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::visitWasmAnyRefJSStringLength(
|
||||||
|
LWasmAnyRefJSStringLength* lir) {
|
||||||
|
Register input = ToRegister(lir->input());
|
||||||
|
Register output = ToRegister(lir->output());
|
||||||
|
Register temp = ToRegister(lir->temp0());
|
||||||
|
Label isJSString;
|
||||||
|
masm.branchWasmAnyRefIsJSString(true, input, temp, &isJSString);
|
||||||
|
masm.wasmTrap(lir->mir()->trap(), lir->mir()->bytecodeOffset());
|
||||||
|
masm.bind(&isJSString);
|
||||||
|
masm.untagWasmAnyRef(input, temp, wasm::AnyRefTag::String);
|
||||||
|
masm.loadStringLength(temp, output);
|
||||||
|
}
|
||||||
|
|
||||||
void CodeGenerator::visitWasmNewI31Ref(LWasmNewI31Ref* lir) {
|
void CodeGenerator::visitWasmNewI31Ref(LWasmNewI31Ref* lir) {
|
||||||
if (lir->value()->isConstant()) {
|
if (lir->value()->isConstant()) {
|
||||||
// i31ref are often created with constants. If that's the case we will
|
// i31ref are often created with constants. If that's the case we will
|
||||||
|
@ -4294,6 +4294,13 @@
|
|||||||
input: WordSized
|
input: WordSized
|
||||||
num_temps: 1
|
num_temps: 1
|
||||||
|
|
||||||
|
- name: WasmAnyRefJSStringLength
|
||||||
|
mir_op: true
|
||||||
|
result_type: WordSized
|
||||||
|
operands:
|
||||||
|
input: WordSized
|
||||||
|
num_temps: 1
|
||||||
|
|
||||||
- name: WasmNewI31Ref
|
- name: WasmNewI31Ref
|
||||||
mir_op: true
|
mir_op: true
|
||||||
result_type: WordSized
|
result_type: WordSized
|
||||||
|
@ -3720,6 +3720,13 @@ void LIRGenerator::visitWasmTrapIfAnyRefIsNotJSString(
|
|||||||
add(lir, ins);
|
add(lir, ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LIRGenerator::visitWasmAnyRefJSStringLength(
|
||||||
|
MWasmAnyRefJSStringLength* ins) {
|
||||||
|
LWasmAnyRefJSStringLength* lir = new (alloc())
|
||||||
|
LWasmAnyRefJSStringLength(useRegisterAtStart(ins->input()), temp());
|
||||||
|
define(lir, ins);
|
||||||
|
}
|
||||||
|
|
||||||
void LIRGenerator::visitWasmNewI31Ref(MWasmNewI31Ref* ins) {
|
void LIRGenerator::visitWasmNewI31Ref(MWasmNewI31Ref* ins) {
|
||||||
// If it's a constant, it will be put directly into the register.
|
// If it's a constant, it will be put directly into the register.
|
||||||
LWasmNewI31Ref* lir =
|
LWasmNewI31Ref* lir =
|
||||||
|
@ -679,6 +679,19 @@
|
|||||||
guard: true
|
guard: true
|
||||||
clone: true
|
clone: true
|
||||||
|
|
||||||
|
- name: WasmAnyRefJSStringLength
|
||||||
|
operands:
|
||||||
|
input: WasmAnyRef
|
||||||
|
arguments:
|
||||||
|
trap: wasm::Trap
|
||||||
|
bytecodeOffset: wasm::BytecodeOffset
|
||||||
|
type_policy: none
|
||||||
|
result_type: Int32
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: none
|
||||||
|
guard: true
|
||||||
|
clone: true
|
||||||
|
|
||||||
- name: WasmNewI31Ref
|
- name: WasmNewI31Ref
|
||||||
operands:
|
operands:
|
||||||
input: Int32
|
input: Int32
|
||||||
|
@ -6973,6 +6973,12 @@ void MacroAssembler::extractWasmAnyRefTag(Register src, Register dest) {
|
|||||||
andPtr(Imm32(int32_t(wasm::AnyRef::TagMask)), dest);
|
andPtr(Imm32(int32_t(wasm::AnyRef::TagMask)), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::untagWasmAnyRef(Register src, Register dest,
|
||||||
|
wasm::AnyRefTag tag) {
|
||||||
|
MOZ_ASSERT(tag != wasm::AnyRefTag::ObjectOrNull, "No untagging needed");
|
||||||
|
computeEffectiveAddress(Address(src, -int32_t(tag)), dest);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroAssembler::branchWasmAnyRefIsNull(bool isNull, Register src,
|
void MacroAssembler::branchWasmAnyRefIsNull(bool isNull, Register src,
|
||||||
Label* label) {
|
Label* label) {
|
||||||
branchTestPtr(isNull ? Assembler::Zero : Assembler::NonZero, src, src, label);
|
branchTestPtr(isNull ? Assembler::Zero : Assembler::NonZero, src, src, label);
|
||||||
@ -7579,8 +7585,7 @@ void MacroAssembler::convertWasmAnyRefToValue(Register instance, Register src,
|
|||||||
&isObjectOrNull);
|
&isObjectOrNull);
|
||||||
|
|
||||||
// If we're not i31, object, or null, we must be a string
|
// If we're not i31, object, or null, we must be a string
|
||||||
rshiftPtr(Imm32(wasm::AnyRef::TagShift), src);
|
untagWasmAnyRef(src, src, wasm::AnyRefTag::String);
|
||||||
lshiftPtr(Imm32(wasm::AnyRef::TagShift), src);
|
|
||||||
moveValue(TypedOrValueRegister(MIRType::String, AnyRegister(src)), dst);
|
moveValue(TypedOrValueRegister(MIRType::String, AnyRegister(src)), dst);
|
||||||
jump(&done);
|
jump(&done);
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "vm/FunctionFlags.h"
|
#include "vm/FunctionFlags.h"
|
||||||
#include "vm/Opcodes.h"
|
#include "vm/Opcodes.h"
|
||||||
#include "vm/RealmFuses.h"
|
#include "vm/RealmFuses.h"
|
||||||
|
#include "wasm/WasmAnyRef.h"
|
||||||
|
|
||||||
// [SMDOC] MacroAssembler multi-platform overview
|
// [SMDOC] MacroAssembler multi-platform overview
|
||||||
//
|
//
|
||||||
@ -4149,6 +4150,9 @@ class MacroAssembler : public MacroAssemblerSpecific {
|
|||||||
// Extract the tag of wasm anyref `src`.
|
// Extract the tag of wasm anyref `src`.
|
||||||
void extractWasmAnyRefTag(Register src, Register dest);
|
void extractWasmAnyRefTag(Register src, Register dest);
|
||||||
|
|
||||||
|
// Remove the known tag of wasm anyref `src`.
|
||||||
|
void untagWasmAnyRef(Register src, Register dest, wasm::AnyRefTag tag);
|
||||||
|
|
||||||
// Branch if the wasm anyref `src` is or is not the null value.
|
// Branch if the wasm anyref `src` is or is not the null value.
|
||||||
void branchWasmAnyRefIsNull(bool isNull, Register src, Label* label);
|
void branchWasmAnyRefIsNull(bool isNull, Register src, Label* label);
|
||||||
// Branch if the wasm anyref `src` is or is not an I31.
|
// Branch if the wasm anyref `src` is or is not an I31.
|
||||||
|
@ -338,6 +338,7 @@
|
|||||||
name: StringLength
|
name: StringLength
|
||||||
type: Args_Int32_GeneralGeneral
|
type: Args_Int32_GeneralGeneral
|
||||||
entry: Instance::stringLength
|
entry: Instance::stringLength
|
||||||
|
inline_op: StringLength
|
||||||
export: length
|
export: length
|
||||||
params:
|
params:
|
||||||
- 'externref'
|
- 'externref'
|
||||||
|
@ -985,6 +985,7 @@ enum class BuiltinInlineOp {
|
|||||||
|
|
||||||
StringCast,
|
StringCast,
|
||||||
StringTest,
|
StringTest,
|
||||||
|
StringLength,
|
||||||
|
|
||||||
// Op limit.
|
// Op limit.
|
||||||
Limit
|
Limit
|
||||||
|
@ -3245,6 +3245,16 @@ class FunctionCompiler {
|
|||||||
return ins;
|
return ins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] MDefinition* stringLength(MDefinition* string) {
|
||||||
|
auto* ins = MWasmAnyRefJSStringLength::New(
|
||||||
|
alloc(), string, wasm::Trap::BadCast, bytecodeOffset());
|
||||||
|
if (!ins) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
curBlock_->add(ins);
|
||||||
|
return ins;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool dispatchInlineBuiltinModuleFunc(
|
[[nodiscard]] bool dispatchInlineBuiltinModuleFunc(
|
||||||
const BuiltinModuleFunc& builtinModuleFunc, const DefVector& params) {
|
const BuiltinModuleFunc& builtinModuleFunc, const DefVector& params) {
|
||||||
BuiltinInlineOp inlineOp = builtinModuleFunc.inlineOp();
|
BuiltinInlineOp inlineOp = builtinModuleFunc.inlineOp();
|
||||||
@ -3270,6 +3280,16 @@ class FunctionCompiler {
|
|||||||
iter().setResult(test);
|
iter().setResult(test);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case BuiltinInlineOp::StringLength: {
|
||||||
|
MOZ_ASSERT(params.length() == 1);
|
||||||
|
MDefinition* string = params[0];
|
||||||
|
MDefinition* length = stringLength(string);
|
||||||
|
if (!length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iter().setResult(length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case BuiltinInlineOp::None:
|
case BuiltinInlineOp::None:
|
||||||
case BuiltinInlineOp::Limit:
|
case BuiltinInlineOp::Limit:
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user