[maglev][arm64] Add StringFromCharCode
... and any other node needed to test it. Bug: v8:7700 Change-Id: Ia37fdcb1db3b6fb986f026696454d443236d011c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4111600 Reviewed-by: Patrick Thier <pthier@chromium.org> Auto-Submit: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Patrick Thier <pthier@chromium.org> Commit-Queue: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/main@{#84893}
This commit is contained in:
parent
3706e2e29a
commit
9c2ac00eb1
1
BUILD.gn
1
BUILD.gn
@ -4848,6 +4848,7 @@ v8_source_set("v8_base_without_compiler") {
|
|||||||
|
|
||||||
if (v8_enable_maglev) {
|
if (v8_enable_maglev) {
|
||||||
sources += [
|
sources += [
|
||||||
|
"src/maglev/maglev-assembler.cc",
|
||||||
"src/maglev/maglev-code-generator.cc",
|
"src/maglev/maglev-code-generator.cc",
|
||||||
"src/maglev/maglev-compilation-info.cc",
|
"src/maglev/maglev-compilation-info.cc",
|
||||||
"src/maglev/maglev-compilation-unit.cc",
|
"src/maglev/maglev-compilation-unit.cc",
|
||||||
|
@ -361,6 +361,12 @@ inline void MaglevAssembler::FinishCode() {
|
|||||||
ForceConstantPoolEmissionWithoutJump();
|
ForceConstantPoolEmissionWithoutJump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename NodeT>
|
||||||
|
inline void MaglevAssembler::EmitEagerDeoptIfNotEqual(DeoptimizeReason reason,
|
||||||
|
NodeT* node) {
|
||||||
|
EmitEagerDeoptIf(ne, reason, node);
|
||||||
|
}
|
||||||
|
|
||||||
inline void MaglevAssembler::MaterialiseValueNode(Register dst,
|
inline void MaglevAssembler::MaterialiseValueNode(Register dst,
|
||||||
ValueNode* value) {
|
ValueNode* value) {
|
||||||
// TODO(v8:7700): Implement!
|
// TODO(v8:7700): Implement!
|
||||||
|
@ -338,6 +338,70 @@ void MaglevAssembler::MaybeEmitDeoptBuiltinsCall(size_t eager_deopt_count,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaglevAssembler::AllocateTwoByteString(RegisterSnapshot register_snapshot,
|
||||||
|
Register result, int length) {
|
||||||
|
Allocate(register_snapshot, result, SeqTwoByteString::SizeFor(length));
|
||||||
|
UseScratchRegisterScope scope(this);
|
||||||
|
Register scratch = scope.AcquireX();
|
||||||
|
LoadRoot(scratch, RootIndex::kStringMap);
|
||||||
|
StoreTaggedField(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
|
||||||
|
Move(scratch, Name::kEmptyHashField);
|
||||||
|
StoreTaggedField(scratch, FieldMemOperand(result, Name::kRawHashFieldOffset));
|
||||||
|
Move(scratch, length);
|
||||||
|
StoreTaggedField(scratch, FieldMemOperand(result, String::kLengthOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaglevAssembler::LoadSingleCharacterString(Register result,
|
||||||
|
Register char_code,
|
||||||
|
Register scratch) {
|
||||||
|
DCHECK_NE(char_code, scratch);
|
||||||
|
if (v8_flags.debug_code) {
|
||||||
|
Cmp(char_code, Immediate(String::kMaxOneByteCharCode));
|
||||||
|
Assert(ls, AbortReason::kUnexpectedValue);
|
||||||
|
}
|
||||||
|
Register table = scratch;
|
||||||
|
LoadRoot(table, RootIndex::kSingleCharacterStringTable);
|
||||||
|
Add(table, table, Operand(char_code, LSL, kTaggedSizeLog2));
|
||||||
|
DecompressAnyTagged(result, FieldMemOperand(table, FixedArray::kHeaderSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaglevAssembler::StringFromCharCode(RegisterSnapshot register_snapshot,
|
||||||
|
Label* char_code_fits_one_byte,
|
||||||
|
Register result, Register char_code,
|
||||||
|
Register scratch) {
|
||||||
|
DCHECK_NE(char_code, scratch);
|
||||||
|
ZoneLabelRef done(this);
|
||||||
|
Cmp(char_code, Immediate(String::kMaxOneByteCharCode));
|
||||||
|
JumpToDeferredIf(
|
||||||
|
hi,
|
||||||
|
[](MaglevAssembler* masm, RegisterSnapshot register_snapshot,
|
||||||
|
ZoneLabelRef done, Register result, Register char_code,
|
||||||
|
Register scratch) {
|
||||||
|
// Be sure to save {char_code}. If it aliases with {result}, use
|
||||||
|
// the scratch register.
|
||||||
|
if (char_code == result) {
|
||||||
|
// This is guaranteed to be true since we've already checked
|
||||||
|
// char_code != scratch.
|
||||||
|
DCHECK_NE(scratch, result);
|
||||||
|
__ Move(scratch, char_code);
|
||||||
|
char_code = scratch;
|
||||||
|
}
|
||||||
|
DCHECK(!register_snapshot.live_tagged_registers.has(char_code));
|
||||||
|
register_snapshot.live_registers.set(char_code);
|
||||||
|
__ AllocateTwoByteString(register_snapshot, result, 1);
|
||||||
|
__ And(scratch, char_code, Immediate(0xFFFF));
|
||||||
|
__ Strh(scratch.W(),
|
||||||
|
FieldMemOperand(result, SeqTwoByteString::kHeaderSize));
|
||||||
|
__ B(*done);
|
||||||
|
},
|
||||||
|
register_snapshot, done, result, char_code, scratch);
|
||||||
|
if (char_code_fits_one_byte != nullptr) {
|
||||||
|
bind(char_code_fits_one_byte);
|
||||||
|
}
|
||||||
|
LoadSingleCharacterString(result, char_code, scratch);
|
||||||
|
bind(*done);
|
||||||
|
}
|
||||||
|
|
||||||
void MaglevAssembler::StringCharCodeAt(RegisterSnapshot& register_snapshot,
|
void MaglevAssembler::StringCharCodeAt(RegisterSnapshot& register_snapshot,
|
||||||
Register result, Register string,
|
Register result, Register string,
|
||||||
Register index, Register not_used,
|
Register index, Register not_used,
|
||||||
@ -478,6 +542,47 @@ void MaglevAssembler::StringCharCodeAt(RegisterSnapshot& register_snapshot,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaglevAssembler::TruncateDoubleToInt32(Register dst, DoubleRegister src) {
|
||||||
|
if (CpuFeatures::IsSupported(JSCVT)) {
|
||||||
|
Fjcvtzs(dst.W(), src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneLabelRef done(this);
|
||||||
|
// Try to convert with an FPU convert instruction. It's trivial to compute
|
||||||
|
// the modulo operation on an integer register so we convert to a 64-bit
|
||||||
|
// integer.
|
||||||
|
//
|
||||||
|
// Fcvtzs will saturate to INT64_MIN (0x800...00) or INT64_MAX (0x7FF...FF)
|
||||||
|
// when the double is out of range. NaNs and infinities will be converted to 0
|
||||||
|
// (as ECMA-262 requires).
|
||||||
|
Fcvtzs(dst.X(), src);
|
||||||
|
|
||||||
|
// The values INT64_MIN (0x800...00) or INT64_MAX (0x7FF...FF) are not
|
||||||
|
// representable using a double, so if the result is one of those then we know
|
||||||
|
// that saturation occurred, and we need to manually handle the conversion.
|
||||||
|
//
|
||||||
|
// It is easy to detect INT64_MIN and INT64_MAX because adding or subtracting
|
||||||
|
// 1 will cause signed overflow.
|
||||||
|
Cmp(dst.X(), 1);
|
||||||
|
Ccmp(dst.X(), -1, VFlag, vc);
|
||||||
|
|
||||||
|
JumpToDeferredIf(
|
||||||
|
vs,
|
||||||
|
[](MaglevAssembler* masm, DoubleRegister src, Register dst,
|
||||||
|
ZoneLabelRef done) {
|
||||||
|
__ MacroAssembler::Push(xzr, src);
|
||||||
|
__ CallBuiltin(Builtin::kDoubleToI);
|
||||||
|
__ Ldr(dst.W(), MemOperand(sp, 0));
|
||||||
|
DCHECK_EQ(xzr.SizeInBytes(), src.SizeInBytes());
|
||||||
|
__ Drop(2);
|
||||||
|
__ B(*done);
|
||||||
|
},
|
||||||
|
src, dst, done);
|
||||||
|
|
||||||
|
Bind(*done);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace maglev
|
} // namespace maglev
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -112,7 +112,6 @@ void Int32DecrementWithOverflow::GenerateCode(MaglevAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(Float64Ieee754Unary)
|
UNIMPLEMENTED_NODE_WITH_CALL(Float64Ieee754Unary)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(BuiltinStringFromCharCode)
|
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(CallBuiltin)
|
UNIMPLEMENTED_NODE_WITH_CALL(CallBuiltin)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(Construct)
|
UNIMPLEMENTED_NODE_WITH_CALL(Construct)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(ConstructWithSpread)
|
UNIMPLEMENTED_NODE_WITH_CALL(ConstructWithSpread)
|
||||||
@ -125,7 +124,6 @@ UNIMPLEMENTED_NODE(LoadUnsignedIntTypedArrayElement, elements_kind_)
|
|||||||
UNIMPLEMENTED_NODE(LoadDoubleTypedArrayElement, elements_kind_)
|
UNIMPLEMENTED_NODE(LoadDoubleTypedArrayElement, elements_kind_)
|
||||||
UNIMPLEMENTED_NODE(CheckedSmiTagUint32)
|
UNIMPLEMENTED_NODE(CheckedSmiTagUint32)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(CheckedObjectToIndex)
|
UNIMPLEMENTED_NODE_WITH_CALL(CheckedObjectToIndex)
|
||||||
UNIMPLEMENTED_NODE(CheckedTruncateNumberToInt32)
|
|
||||||
UNIMPLEMENTED_NODE(CheckedInt32ToUint32)
|
UNIMPLEMENTED_NODE(CheckedInt32ToUint32)
|
||||||
UNIMPLEMENTED_NODE(CheckedUint32ToInt32)
|
UNIMPLEMENTED_NODE(CheckedUint32ToInt32)
|
||||||
UNIMPLEMENTED_NODE(ChangeInt32ToFloat64)
|
UNIMPLEMENTED_NODE(ChangeInt32ToFloat64)
|
||||||
@ -143,7 +141,6 @@ UNIMPLEMENTED_NODE(TestTypeOf, literal_)
|
|||||||
UNIMPLEMENTED_NODE_WITH_CALL(ToObject)
|
UNIMPLEMENTED_NODE_WITH_CALL(ToObject)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(ToString)
|
UNIMPLEMENTED_NODE_WITH_CALL(ToString)
|
||||||
UNIMPLEMENTED_NODE(AssertInt32, condition_, reason_)
|
UNIMPLEMENTED_NODE(AssertInt32, condition_, reason_)
|
||||||
UNIMPLEMENTED_NODE(CheckDynamicValue)
|
|
||||||
UNIMPLEMENTED_NODE(CheckUint32IsSmi)
|
UNIMPLEMENTED_NODE(CheckUint32IsSmi)
|
||||||
UNIMPLEMENTED_NODE(CheckHeapObject)
|
UNIMPLEMENTED_NODE(CheckHeapObject)
|
||||||
UNIMPLEMENTED_NODE(CheckJSArrayBounds)
|
UNIMPLEMENTED_NODE(CheckJSArrayBounds)
|
||||||
@ -153,9 +150,7 @@ UNIMPLEMENTED_NODE(CheckJSTypedArrayBounds, elements_kind_)
|
|||||||
UNIMPLEMENTED_NODE(CheckMaps, check_type_)
|
UNIMPLEMENTED_NODE(CheckMaps, check_type_)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(CheckMapsWithMigration, check_type_)
|
UNIMPLEMENTED_NODE_WITH_CALL(CheckMapsWithMigration, check_type_)
|
||||||
UNIMPLEMENTED_NODE(CheckNumber)
|
UNIMPLEMENTED_NODE(CheckNumber)
|
||||||
UNIMPLEMENTED_NODE(CheckSmi)
|
|
||||||
UNIMPLEMENTED_NODE(CheckString, check_type_)
|
UNIMPLEMENTED_NODE(CheckString, check_type_)
|
||||||
UNIMPLEMENTED_NODE(CheckValue)
|
|
||||||
UNIMPLEMENTED_NODE(CheckInstanceType, check_type_)
|
UNIMPLEMENTED_NODE(CheckInstanceType, check_type_)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(GeneratorStore)
|
UNIMPLEMENTED_NODE_WITH_CALL(GeneratorStore)
|
||||||
UNIMPLEMENTED_NODE_WITH_CALL(JumpLoopPrologue, loop_depth_, unit_)
|
UNIMPLEMENTED_NODE_WITH_CALL(JumpLoopPrologue, loop_depth_, unit_)
|
||||||
@ -173,6 +168,38 @@ UNIMPLEMENTED_NODE(BranchIfUndefinedOrNull)
|
|||||||
UNIMPLEMENTED_NODE(BranchIfJSReceiver)
|
UNIMPLEMENTED_NODE(BranchIfJSReceiver)
|
||||||
UNIMPLEMENTED_NODE(Switch)
|
UNIMPLEMENTED_NODE(Switch)
|
||||||
|
|
||||||
|
int BuiltinStringFromCharCode::MaxCallStackArgs() const {
|
||||||
|
return AllocateDescriptor::GetStackParameterCount();
|
||||||
|
}
|
||||||
|
void BuiltinStringFromCharCode::SetValueLocationConstraints() {
|
||||||
|
if (code_input().node()->Is<Int32Constant>()) {
|
||||||
|
UseAny(code_input());
|
||||||
|
} else {
|
||||||
|
UseRegister(code_input());
|
||||||
|
set_temporaries_needed(1);
|
||||||
|
}
|
||||||
|
DefineAsRegister(this);
|
||||||
|
}
|
||||||
|
void BuiltinStringFromCharCode::GenerateCode(MaglevAssembler* masm,
|
||||||
|
const ProcessingState& state) {
|
||||||
|
Register scratch = general_temporaries().PopFirst();
|
||||||
|
Register result_string = ToRegister(result());
|
||||||
|
if (Int32Constant* constant = code_input().node()->TryCast<Int32Constant>()) {
|
||||||
|
int32_t char_code = constant->value();
|
||||||
|
if (0 <= char_code && char_code < String::kMaxOneByteCharCode) {
|
||||||
|
__ LoadSingleCharacterString(result_string, char_code);
|
||||||
|
} else {
|
||||||
|
__ AllocateTwoByteString(register_snapshot(), result_string, 1);
|
||||||
|
__ Move(scratch, char_code & 0xFFFF);
|
||||||
|
__ Strh(scratch.W(),
|
||||||
|
FieldMemOperand(result_string, SeqTwoByteString::kHeaderSize));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
__ StringFromCharCode(register_snapshot(), nullptr, result_string,
|
||||||
|
ToRegister(code_input()), scratch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int BuiltinStringPrototypeCharCodeAt::MaxCallStackArgs() const {
|
int BuiltinStringPrototypeCharCodeAt::MaxCallStackArgs() const {
|
||||||
DCHECK_EQ(Runtime::FunctionForId(Runtime::kStringCharCodeAt)->nargs, 2);
|
DCHECK_EQ(Runtime::FunctionForId(Runtime::kStringCharCodeAt)->nargs, 2);
|
||||||
return 2;
|
return 2;
|
||||||
@ -219,6 +246,33 @@ void CreateEmptyObjectLiteral::GenerateCode(MaglevAssembler* masm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckedTruncateNumberToInt32::SetValueLocationConstraints() {
|
||||||
|
UseRegister(input());
|
||||||
|
DefineAsRegister(this);
|
||||||
|
}
|
||||||
|
void CheckedTruncateNumberToInt32::GenerateCode(MaglevAssembler* masm,
|
||||||
|
const ProcessingState& state) {
|
||||||
|
Register value = ToRegister(input());
|
||||||
|
Register result_reg = ToRegister(result());
|
||||||
|
Label is_not_smi, done;
|
||||||
|
// Check if Smi.
|
||||||
|
__ JumpIfNotSmi(value, &is_not_smi);
|
||||||
|
// If Smi, convert to Int32.
|
||||||
|
__ SmiToInt32(result_reg, value);
|
||||||
|
__ B(&done);
|
||||||
|
__ bind(&is_not_smi);
|
||||||
|
// Check if HeapNumber, deopt otherwise.
|
||||||
|
UseScratchRegisterScope temps(masm);
|
||||||
|
Register scratch = temps.AcquireW();
|
||||||
|
__ Ldr(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
|
||||||
|
__ CompareRoot(scratch, RootIndex::kHeapNumberMap);
|
||||||
|
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kNotANumber, this);
|
||||||
|
DoubleRegister double_value = temps.AcquireD();
|
||||||
|
__ Ldr(double_value, FieldMemOperand(value, HeapNumber::kValueOffset));
|
||||||
|
__ TruncateDoubleToInt32(result_reg, double_value);
|
||||||
|
__ bind(&done);
|
||||||
|
}
|
||||||
|
|
||||||
void CheckSymbol::SetValueLocationConstraints() {
|
void CheckSymbol::SetValueLocationConstraints() {
|
||||||
UseRegister(receiver_input());
|
UseRegister(receiver_input());
|
||||||
}
|
}
|
||||||
|
32
src/maglev/maglev-assembler.cc
Normal file
32
src/maglev/maglev-assembler.cc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2022 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.
|
||||||
|
|
||||||
|
#include "src/maglev/maglev-code-generator.h"
|
||||||
|
|
||||||
|
#ifdef V8_TARGET_ARCH_ARM64
|
||||||
|
#include "src/maglev/arm64/maglev-assembler-arm64-inl.h"
|
||||||
|
#elif V8_TARGET_ARCH_X64
|
||||||
|
#include "src/maglev/x64/maglev-assembler-x64-inl.h"
|
||||||
|
#else
|
||||||
|
#error "Maglev does not supported this architecture."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace internal {
|
||||||
|
namespace maglev {
|
||||||
|
|
||||||
|
void MaglevAssembler::LoadSingleCharacterString(Register result,
|
||||||
|
int char_code) {
|
||||||
|
DCHECK_GE(char_code, 0);
|
||||||
|
DCHECK_LT(char_code, String::kMaxOneByteCharCode);
|
||||||
|
Register table = result;
|
||||||
|
LoadRoot(table, RootIndex::kSingleCharacterStringTable);
|
||||||
|
DecompressAnyTagged(
|
||||||
|
result, FieldMemOperand(
|
||||||
|
table, FixedArray::kHeaderSize + char_code * kTaggedSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace maglev
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace v8
|
@ -127,6 +127,8 @@ class MaglevAssembler : public MacroAssembler {
|
|||||||
template <typename NodeT>
|
template <typename NodeT>
|
||||||
inline void EmitEagerDeoptIf(Condition cond, DeoptimizeReason reason,
|
inline void EmitEagerDeoptIf(Condition cond, DeoptimizeReason reason,
|
||||||
NodeT* node);
|
NodeT* node);
|
||||||
|
template <typename NodeT>
|
||||||
|
inline void EmitEagerDeoptIfNotEqual(DeoptimizeReason reason, NodeT* node);
|
||||||
|
|
||||||
inline void MaterialiseValueNode(Register dst, ValueNode* value);
|
inline void MaterialiseValueNode(Register dst, ValueNode* value);
|
||||||
|
|
||||||
|
@ -915,6 +915,35 @@ void StoreGlobal::GenerateCode(MaglevAssembler* masm,
|
|||||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckValue::SetValueLocationConstraints() { UseRegister(target_input()); }
|
||||||
|
void CheckValue::GenerateCode(MaglevAssembler* masm,
|
||||||
|
const ProcessingState& state) {
|
||||||
|
Register target = ToRegister(target_input());
|
||||||
|
__ Cmp(target, value().object());
|
||||||
|
__ EmitEagerDeoptIfNotEqual(DeoptimizeReason::kWrongValue, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckDynamicValue::SetValueLocationConstraints() {
|
||||||
|
UseRegister(first_input());
|
||||||
|
UseRegister(second_input());
|
||||||
|
}
|
||||||
|
void CheckDynamicValue::GenerateCode(MaglevAssembler* masm,
|
||||||
|
const ProcessingState& state) {
|
||||||
|
Register first = ToRegister(first_input());
|
||||||
|
Register second = ToRegister(second_input());
|
||||||
|
__ CompareInt32(first, second);
|
||||||
|
__ EmitEagerDeoptIfNotEqual(DeoptimizeReason::kWrongValue, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckSmi::SetValueLocationConstraints() { UseRegister(receiver_input()); }
|
||||||
|
void CheckSmi::GenerateCode(MaglevAssembler* masm,
|
||||||
|
const ProcessingState& state) {
|
||||||
|
Register object = ToRegister(receiver_input());
|
||||||
|
Condition is_smi = __ CheckSmi(object);
|
||||||
|
__ EmitEagerDeoptIf(NegateCondition(is_smi), DeoptimizeReason::kNotASmi,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
void CheckInt32Condition::SetValueLocationConstraints() {
|
void CheckInt32Condition::SetValueLocationConstraints() {
|
||||||
UseRegister(left_input());
|
UseRegister(left_input());
|
||||||
UseRegister(right_input());
|
UseRegister(right_input());
|
||||||
|
@ -329,6 +329,12 @@ inline void MaglevAssembler::JumpIfTaggedEqual(Register r1, Register r2,
|
|||||||
|
|
||||||
inline void MaglevAssembler::Pop(Register dst) { MacroAssembler::Pop(dst); }
|
inline void MaglevAssembler::Pop(Register dst) { MacroAssembler::Pop(dst); }
|
||||||
|
|
||||||
|
template <typename NodeT>
|
||||||
|
inline void MaglevAssembler::EmitEagerDeoptIfNotEqual(DeoptimizeReason reason,
|
||||||
|
NodeT* node) {
|
||||||
|
EmitEagerDeoptIf(not_equal, reason, node);
|
||||||
|
}
|
||||||
|
|
||||||
inline void MaglevAssembler::MaterialiseValueNode(Register dst,
|
inline void MaglevAssembler::MaterialiseValueNode(Register dst,
|
||||||
ValueNode* value) {
|
ValueNode* value) {
|
||||||
switch (value->opcode()) {
|
switch (value->opcode()) {
|
||||||
|
@ -97,16 +97,6 @@ void MaglevAssembler::AllocateTwoByteString(RegisterSnapshot register_snapshot,
|
|||||||
Immediate(length));
|
Immediate(length));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaglevAssembler::LoadSingleCharacterString(Register result,
|
|
||||||
int char_code) {
|
|
||||||
DCHECK_GE(char_code, 0);
|
|
||||||
DCHECK_LT(char_code, String::kMaxOneByteCharCode);
|
|
||||||
Register table = result;
|
|
||||||
LoadRoot(table, RootIndex::kSingleCharacterStringTable);
|
|
||||||
DecompressAnyTagged(result, FieldOperand(table, FixedArray::kHeaderSize +
|
|
||||||
char_code * kTaggedSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaglevAssembler::LoadSingleCharacterString(Register result,
|
void MaglevAssembler::LoadSingleCharacterString(Register result,
|
||||||
Register char_code,
|
Register char_code,
|
||||||
Register scratch) {
|
Register scratch) {
|
||||||
|
@ -297,37 +297,6 @@ void CheckMaps::GenerateCode(MaglevAssembler* masm,
|
|||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckValue::SetValueLocationConstraints() { UseRegister(target_input()); }
|
|
||||||
void CheckValue::GenerateCode(MaglevAssembler* masm,
|
|
||||||
const ProcessingState& state) {
|
|
||||||
Register target = ToRegister(target_input());
|
|
||||||
|
|
||||||
__ Cmp(target, value().object());
|
|
||||||
__ EmitEagerDeoptIf(not_equal, DeoptimizeReason::kWrongValue, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckDynamicValue::SetValueLocationConstraints() {
|
|
||||||
UseRegister(first_input());
|
|
||||||
UseRegister(second_input());
|
|
||||||
}
|
|
||||||
void CheckDynamicValue::GenerateCode(MaglevAssembler* masm,
|
|
||||||
const ProcessingState& state) {
|
|
||||||
Register first = ToRegister(first_input());
|
|
||||||
Register second = ToRegister(second_input());
|
|
||||||
|
|
||||||
__ cmpl(first, second);
|
|
||||||
__ EmitEagerDeoptIf(not_equal, DeoptimizeReason::kWrongValue, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckSmi::SetValueLocationConstraints() { UseRegister(receiver_input()); }
|
|
||||||
void CheckSmi::GenerateCode(MaglevAssembler* masm,
|
|
||||||
const ProcessingState& state) {
|
|
||||||
Register object = ToRegister(receiver_input());
|
|
||||||
Condition is_smi = __ CheckSmi(object);
|
|
||||||
__ EmitEagerDeoptIf(NegateCondition(is_smi), DeoptimizeReason::kNotASmi,
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckNumber::SetValueLocationConstraints() {
|
void CheckNumber::SetValueLocationConstraints() {
|
||||||
UseRegister(receiver_input());
|
UseRegister(receiver_input());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user