Add full TurboFan support for accessing SeqString contents.
LOG=n Review URL: https://codereview.chromium.org/1013753016 Cr-Commit-Position: refs/heads/master@{#27465}
This commit is contained in:
parent
46cc8740a9
commit
4518e92706
@ -116,6 +116,21 @@ ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type,
|
||||
return {kUntaggedBase, 0, Type::None(), kMachNone};
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ElementAccess AccessBuilder::ForSeqStringChar(String::Encoding encoding) {
|
||||
switch (encoding) {
|
||||
case String::ONE_BYTE_ENCODING:
|
||||
return {kTaggedBase, SeqString::kHeaderSize, Type::Unsigned32(),
|
||||
kMachUint8};
|
||||
case String::TWO_BYTE_ENCODING:
|
||||
return {kTaggedBase, SeqString::kHeaderSize, Type::Unsigned32(),
|
||||
kMachUint16};
|
||||
}
|
||||
UNREACHABLE();
|
||||
return {kUntaggedBase, 0, Type::None(), kMachNone};
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -53,6 +53,9 @@ class AccessBuilder FINAL : public AllStatic {
|
||||
static ElementAccess ForTypedArrayElement(ExternalArrayType type,
|
||||
bool is_external);
|
||||
|
||||
// Provides access to the charaters of sequential strings.
|
||||
static ElementAccess ForSeqStringChar(String::Encoding encoding);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AccessBuilder);
|
||||
};
|
||||
|
@ -53,8 +53,16 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
||||
return ReduceMathFloor(node);
|
||||
case Runtime::kInlineMathSqrt:
|
||||
return ReduceMathSqrt(node);
|
||||
case Runtime::kInlineOneByteSeqStringGetChar:
|
||||
return ReduceSeqStringGetChar(node, String::ONE_BYTE_ENCODING);
|
||||
case Runtime::kInlineOneByteSeqStringSetChar:
|
||||
return ReduceSeqStringSetChar(node, String::ONE_BYTE_ENCODING);
|
||||
case Runtime::kInlineStringGetLength:
|
||||
return ReduceStringGetLength(node);
|
||||
case Runtime::kInlineTwoByteSeqStringGetChar:
|
||||
return ReduceSeqStringGetChar(node, String::TWO_BYTE_ENCODING);
|
||||
case Runtime::kInlineTwoByteSeqStringSetChar:
|
||||
return ReduceSeqStringSetChar(node, String::TWO_BYTE_ENCODING);
|
||||
case Runtime::kInlineValueOf:
|
||||
return ReduceValueOf(node);
|
||||
default:
|
||||
@ -221,6 +229,42 @@ Reduction JSIntrinsicLowering::ReduceMathSqrt(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceSeqStringGetChar(
|
||||
Node* node, String::Encoding encoding) {
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
node->set_op(
|
||||
simplified()->LoadElement(AccessBuilder::ForSeqStringChar(encoding)));
|
||||
node->ReplaceInput(2, effect);
|
||||
node->ReplaceInput(3, control);
|
||||
node->TrimInputCount(4);
|
||||
NodeProperties::ReplaceWithValue(node, node, node);
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceSeqStringSetChar(
|
||||
Node* node, String::Encoding encoding) {
|
||||
// Note: The intrinsic has a strange argument order, so we need to reshuffle.
|
||||
Node* index = NodeProperties::GetValueInput(node, 0);
|
||||
Node* chr = NodeProperties::GetValueInput(node, 1);
|
||||
Node* string = NodeProperties::GetValueInput(node, 2);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
node->set_op(
|
||||
simplified()->StoreElement(AccessBuilder::ForSeqStringChar(encoding)));
|
||||
node->ReplaceInput(0, string);
|
||||
node->ReplaceInput(1, index);
|
||||
node->ReplaceInput(2, chr);
|
||||
node->ReplaceInput(3, effect);
|
||||
node->ReplaceInput(4, control);
|
||||
node->TrimInputCount(5);
|
||||
NodeProperties::RemoveBounds(node);
|
||||
NodeProperties::ReplaceWithValue(node, string, node);
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceStringGetLength(Node* node) {
|
||||
Node* value = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
|
@ -40,6 +40,8 @@ class JSIntrinsicLowering FINAL : public Reducer {
|
||||
Reduction ReduceMathClz32(Node* node);
|
||||
Reduction ReduceMathFloor(Node* node);
|
||||
Reduction ReduceMathSqrt(Node* node);
|
||||
Reduction ReduceSeqStringGetChar(Node* node, String::Encoding encoding);
|
||||
Reduction ReduceSeqStringSetChar(Node* node, String::Encoding encoding);
|
||||
Reduction ReduceStringGetLength(Node* node);
|
||||
Reduction ReduceValueOf(Node* node);
|
||||
|
||||
|
@ -1265,6 +1265,15 @@ RUNTIME_FUNCTION(Runtime_StringCharAt) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_OneByteSeqStringGetChar) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK(args.length() == 2);
|
||||
CONVERT_ARG_CHECKED(SeqOneByteString, string, 0);
|
||||
CONVERT_INT32_ARG_CHECKED(index, 1);
|
||||
return Smi::FromInt(string->SeqOneByteStringGet(index));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_OneByteSeqStringSetChar) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK(args.length() == 3);
|
||||
@ -1276,6 +1285,15 @@ RUNTIME_FUNCTION(Runtime_OneByteSeqStringSetChar) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_TwoByteSeqStringGetChar) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK(args.length() == 2);
|
||||
CONVERT_ARG_CHECKED(SeqTwoByteString, string, 0);
|
||||
CONVERT_INT32_ARG_CHECKED(index, 1);
|
||||
return Smi::FromInt(string->SeqTwoByteStringGet(index));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_TwoByteSeqStringSetChar) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK(args.length() == 3);
|
||||
|
@ -646,7 +646,9 @@ namespace internal {
|
||||
F(DateField, 2 /* date object, field index */, 1) \
|
||||
F(StringCharFromCode, 1, 1) \
|
||||
F(StringCharAt, 2, 1) \
|
||||
F(OneByteSeqStringGetChar, 2, 1) \
|
||||
F(OneByteSeqStringSetChar, 3, 1) \
|
||||
F(TwoByteSeqStringGetChar, 2, 1) \
|
||||
F(TwoByteSeqStringSetChar, 3, 1) \
|
||||
F(ObjectEquals, 2, 1) \
|
||||
F(IsObject, 1, 1) \
|
||||
|
@ -176,6 +176,39 @@ TEST(ObjectEquals) {
|
||||
}
|
||||
|
||||
|
||||
TEST(OneByteSeqStringGetChar) {
|
||||
FLAG_turbo_deoptimization = true;
|
||||
FunctionTester T("(function(a,b) { return %_OneByteSeqStringGetChar(a,b); })",
|
||||
flags);
|
||||
|
||||
Handle<SeqOneByteString> string =
|
||||
T.main_isolate()->factory()->NewRawOneByteString(3).ToHandleChecked();
|
||||
string->SeqOneByteStringSet(0, 'b');
|
||||
string->SeqOneByteStringSet(1, 'a');
|
||||
string->SeqOneByteStringSet(2, 'r');
|
||||
T.CheckCall(T.Val('b'), string, T.Val(0.0));
|
||||
T.CheckCall(T.Val('a'), string, T.Val(1));
|
||||
T.CheckCall(T.Val('r'), string, T.Val(2));
|
||||
}
|
||||
|
||||
|
||||
TEST(OneByteSeqStringSetChar) {
|
||||
FLAG_turbo_deoptimization = true;
|
||||
FunctionTester T("(function(a,b) { %_OneByteSeqStringSetChar(a,88,b); })",
|
||||
flags);
|
||||
|
||||
Handle<SeqOneByteString> string =
|
||||
T.main_isolate()->factory()->NewRawOneByteString(3).ToHandleChecked();
|
||||
string->SeqOneByteStringSet(0, 'b');
|
||||
string->SeqOneByteStringSet(1, 'a');
|
||||
string->SeqOneByteStringSet(2, 'r');
|
||||
T.Call(T.Val(1), string);
|
||||
CHECK_EQ('b', string->SeqOneByteStringGet(0));
|
||||
CHECK_EQ('X', string->SeqOneByteStringGet(1));
|
||||
CHECK_EQ('r', string->SeqOneByteStringGet(2));
|
||||
}
|
||||
|
||||
|
||||
TEST(SetValueOf) {
|
||||
FLAG_turbo_deoptimization = true;
|
||||
FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
|
||||
@ -247,6 +280,39 @@ TEST(SubString) {
|
||||
}
|
||||
|
||||
|
||||
TEST(TwoByteSeqStringGetChar) {
|
||||
FLAG_turbo_deoptimization = true;
|
||||
FunctionTester T("(function(a,b) { return %_TwoByteSeqStringGetChar(a,b); })",
|
||||
flags);
|
||||
|
||||
Handle<SeqTwoByteString> string =
|
||||
T.main_isolate()->factory()->NewRawTwoByteString(3).ToHandleChecked();
|
||||
string->SeqTwoByteStringSet(0, 'b');
|
||||
string->SeqTwoByteStringSet(1, 'a');
|
||||
string->SeqTwoByteStringSet(2, 'r');
|
||||
T.CheckCall(T.Val('b'), string, T.Val(0.0));
|
||||
T.CheckCall(T.Val('a'), string, T.Val(1));
|
||||
T.CheckCall(T.Val('r'), string, T.Val(2));
|
||||
}
|
||||
|
||||
|
||||
TEST(TwoByteSeqStringSetChar) {
|
||||
FLAG_turbo_deoptimization = true;
|
||||
FunctionTester T("(function(a,b) { %_TwoByteSeqStringSetChar(a,88,b); })",
|
||||
flags);
|
||||
|
||||
Handle<SeqTwoByteString> string =
|
||||
T.main_isolate()->factory()->NewRawTwoByteString(3).ToHandleChecked();
|
||||
string->SeqTwoByteStringSet(0, 'b');
|
||||
string->SeqTwoByteStringSet(1, 'a');
|
||||
string->SeqTwoByteStringSet(2, 'r');
|
||||
T.Call(T.Val(1), string);
|
||||
CHECK_EQ('b', string->SeqTwoByteStringGet(0));
|
||||
CHECK_EQ('X', string->SeqTwoByteStringGet(1));
|
||||
CHECK_EQ('r', string->SeqTwoByteStringGet(2));
|
||||
}
|
||||
|
||||
|
||||
TEST(ValueOf) {
|
||||
FLAG_turbo_deoptimization = true;
|
||||
FunctionTester T("(function(a) { return %_ValueOf(a); })", flags);
|
||||
|
Loading…
Reference in New Issue
Block a user