Skip to content

Commit

Permalink
Bug 1874683 - Part 11: Transpile LoadStringAtResult. r=jandem
Browse files Browse the repository at this point in the history
Transpile `LoadStringAtResult` similar to how `LoadStringCharResult` is processed.

Differential Revision: https://phabricator.services.mozilla.com/D198567
  • Loading branch information
anba committed Jan 22, 2024
1 parent 59716a0 commit 363a33c
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 2 deletions.
4 changes: 2 additions & 2 deletions js/src/jit/CacheIROps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2192,7 +2192,7 @@

- name: ToRelativeStringIndex
shared: true
transpile: false
transpile: true
cost_estimate: 1
args:
index: Int32Id
Expand All @@ -2210,7 +2210,7 @@

- name: LoadStringAtResult
shared: false
transpile: false
transpile: true
cost_estimate: 5
args:
str: StringId
Expand Down
35 changes: 35 additions & 0 deletions js/src/jit/CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12169,6 +12169,16 @@ void CodeGenerator::visitLinearizeForCodePointAccess(
masm.bind(ool->rejoin());
}

void CodeGenerator::visitToRelativeStringIndex(LToRelativeStringIndex* lir) {
Register index = ToRegister(lir->index());
Register length = ToRegister(lir->length());
Register output = ToRegister(lir->output());

masm.move32(Imm32(0), output);
masm.cmp32Move32(Assembler::LessThan, index, Imm32(0), length, output);
masm.add32(index, output);
}

void CodeGenerator::visitCharCodeAt(LCharCodeAt* lir) {
Register str = ToRegister(lir->str());
Register output = ToRegister(lir->output());
Expand Down Expand Up @@ -12319,6 +12329,31 @@ void CodeGenerator::visitFromCharCodeEmptyIfNegative(
masm.bind(ool->rejoin());
}

void CodeGenerator::visitFromCharCodeUndefinedIfNegative(
LFromCharCodeUndefinedIfNegative* lir) {
Register code = ToRegister(lir->code());
ValueOperand output = ToOutValue(lir);
Register temp = output.scratchReg();

using Fn = JSLinearString* (*)(JSContext*, int32_t);
auto* ool = oolCallVM<Fn, js::StringFromCharCode>(lir, ArgList(code),
StoreRegisterTo(temp));

// Return |undefined| for negative inputs.
Label done;
masm.moveValue(UndefinedValue(), output);
masm.branchTest32(Assembler::Signed, code, code, &done);

// OOL path if code >= UNIT_STATIC_LIMIT.
masm.lookupStaticString(code, temp, gen->runtime->staticStrings(),
ool->entry());

masm.bind(ool->rejoin());
masm.tagValue(JSVAL_TYPE_STRING, temp, output);

masm.bind(&done);
}

void CodeGenerator::visitFromCodePoint(LFromCodePoint* lir) {
Register codePoint = ToRegister(lir->codePoint());
Register output = ToRegister(lir->output());
Expand Down
15 changes: 15 additions & 0 deletions js/src/jit/LIROps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,14 @@
num_temps: 1
mir_op: true

# Compute the relative string index.
- name: ToRelativeStringIndex
result_type: WordSized
operands:
index: WordSized
length: WordSized
mir_op: true

# Get uint16 character code from a string.
- name: CharCodeAt
result_type: WordSized
Expand Down Expand Up @@ -1256,6 +1264,13 @@
operands:
code: WordSized

# Convert non-negative input as a uint16 character code to a string. If the
# input is negative, return the undefined value.
- name: FromCharCodeUndefinedIfNegative
result_type: BoxedValue
operands:
code: WordSized

# Convert uint32 code point to a string.
- name: FromCodePoint
result_type: WordSized
Expand Down
23 changes: 23 additions & 0 deletions js/src/jit/Lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2492,6 +2492,18 @@ void LIRGenerator::visitLinearizeForCodePointAccess(
assignSafepoint(lir, ins);
}

void LIRGenerator::visitToRelativeStringIndex(MToRelativeStringIndex* ins) {
MDefinition* index = ins->index();
MDefinition* length = ins->length();

MOZ_ASSERT(index->type() == MIRType::Int32);
MOZ_ASSERT(length->type() == MIRType::Int32);

auto* lir = new (alloc())
LToRelativeStringIndex(useRegister(index), useRegister(length));
define(lir, ins);
}

void LIRGenerator::visitCharCodeAt(MCharCodeAt* ins) {
MDefinition* str = ins->string();
MDefinition* idx = ins->index();
Expand Down Expand Up @@ -2579,6 +2591,17 @@ void LIRGenerator::visitFromCharCodeEmptyIfNegative(
assignSafepoint(lir, ins);
}

void LIRGenerator::visitFromCharCodeUndefinedIfNegative(
MFromCharCodeUndefinedIfNegative* ins) {
MDefinition* code = ins->code();

MOZ_ASSERT(code->type() == MIRType::Int32);

auto* lir = new (alloc()) LFromCharCodeUndefinedIfNegative(useRegister(code));
defineBox(lir, ins);
assignSafepoint(lir, ins);
}

void LIRGenerator::visitFromCodePoint(MFromCodePoint* ins) {
MDefinition* codePoint = ins->codePoint();

Expand Down
21 changes: 21 additions & 0 deletions js/src/jit/MIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,27 @@ MDefinition* MCodePointAt::foldsTo(TempAllocator& alloc) {
return MConstant::New(alloc, Int32Value(first));
}

MDefinition* MToRelativeStringIndex::foldsTo(TempAllocator& alloc) {
MDefinition* index = this->index();
MDefinition* length = this->length();

if (!index->isConstant()) {
return this;
}
if (!length->isStringLength() && !length->isConstant()) {
return this;
}
MOZ_ASSERT_IF(length->isConstant(), length->toConstant()->toInt32() >= 0);

int32_t relativeIndex = index->toConstant()->toInt32();
if (relativeIndex >= 0) {
return index;
}

// Safe to truncate because |length| is never negative.
return MAdd::New(alloc, index, length, TruncateKind::Truncate);
}

template <size_t Arity>
[[nodiscard]] static bool EnsureFloatInputOrConvert(
MAryInstruction<Arity>* owner, TempAllocator& alloc) {
Expand Down
19 changes: 19 additions & 0 deletions js/src/jit/MIROps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,16 @@
# Strings are immutable, so there is no implicit dependency.
alias_set: none

- name: ToRelativeStringIndex
operands:
index: Int32
length: Int32
result_type: Int32
movable: true
folds_to: custom
congruent_to: if_operands_equal
alias_set: none

- name: CharCodeAt
operands:
string: String
Expand Down Expand Up @@ -1029,6 +1039,15 @@
can_recover: true
clone: true

# Similar to FromCharCode, but returns the |undefined| if the input is negative.
- name: FromCharCodeUndefinedIfNegative
operands:
code: Int32
result_type: Value
movable: true
congruent_to: if_operands_equal
alias_set: none

- name: FromCodePoint
operands:
codePoint: Int32
Expand Down
48 changes: 48 additions & 0 deletions js/src/jit/WarpCacheIRTranspiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,21 @@ bool WarpCacheIRTranspiler::emitLinearizeForCodePointAccess(
return defineOperand(resultId, ins);
}

bool WarpCacheIRTranspiler::emitToRelativeStringIndex(Int32OperandId indexId,
StringOperandId strId,
Int32OperandId resultId) {
MDefinition* str = getOperand(strId);
MDefinition* index = getOperand(indexId);

auto* length = MStringLength::New(alloc(), str);
add(length);

auto* ins = MToRelativeStringIndex::New(alloc(), index, length);
add(ins);

return defineOperand(resultId, ins);
}

bool WarpCacheIRTranspiler::emitLoadStringCharResult(StringOperandId strId,
Int32OperandId indexId,
bool handleOOB) {
Expand Down Expand Up @@ -2207,6 +2222,39 @@ bool WarpCacheIRTranspiler::emitLoadStringCharResult(StringOperandId strId,
return true;
}

bool WarpCacheIRTranspiler::emitLoadStringAtResult(StringOperandId strId,
Int32OperandId indexId,
bool handleOOB) {
MDefinition* str = getOperand(strId);
MDefinition* index = getOperand(indexId);

if (handleOOB) {
auto* charCode = MCharCodeAtOrNegative::New(alloc(), str, index);
add(charCode);

auto* fromCharCode =
MFromCharCodeUndefinedIfNegative::New(alloc(), charCode);
add(fromCharCode);

pushResult(fromCharCode);
return true;
}

auto* length = MStringLength::New(alloc(), str);
add(length);

index = addBoundsCheck(index, length);

auto* charCode = MCharCodeAt::New(alloc(), str, index);
add(charCode);

auto* fromCharCode = MFromCharCode::New(alloc(), charCode);
add(fromCharCode);

pushResult(fromCharCode);
return true;
}

bool WarpCacheIRTranspiler::emitLoadStringCharCodeResult(StringOperandId strId,
Int32OperandId indexId,
bool handleOOB) {
Expand Down

0 comments on commit 363a33c

Please sign in to comment.