Revert "[turbofan] Add simplified operator for String.prototype.codePointAt"

This reverts commit 22d894c83e.

Reason for revert:
https://build.chromium.org/p/client.v8.ports/builders/V8%20Mips%20-%20builder/builds/14553

Original change's description:
> [turbofan] Add simplified operator for String.prototype.codePointAt
> 
> This CL adds the simplified operators
>   StringCodePointAt
>   SeqStringCodePointAt
> and associated lowering.
> 
> Bug: v8:7270
> Change-Id: I5aeefddeec39c3119b2d225e92a3116f802e7b45
> Reviewed-on: https://chromium-review.googlesource.com/861789
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Peter Marshall <petermarshall@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#50547}

TBR=sigurds@chromium.org,petermarshall@chromium.org,bmeurer@chromium.org

Change-Id: If07881fce121538cc4abc72ed5eaa42dd7829101
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7270
Reviewed-on: https://chromium-review.googlesource.com/864662
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50548}
This commit is contained in:
Michael Achenbach 2018-01-12 16:16:55 +00:00 committed by Commit Bot
parent 22d894c83e
commit 211eb85f91
12 changed files with 37 additions and 169 deletions

View File

@ -91,9 +91,8 @@ namespace internal {
ASM(StackCheck) \
\
/* String helpers */ \
TFC(StringCharAt, StringAt, 1) \
TFC(StringCharCodeAt, StringAt, 1) \
TFC(StringCodePointAt, StringAt, 1) \
TFC(StringCharAt, StringCharAt, 1) \
TFC(StringCharCodeAt, StringCharCodeAt, 1) \
TFC(StringEqual, Compare, 1) \
TFC(StringGreaterThan, Compare, 1) \
TFC(StringGreaterThanOrEqual, Compare, 1) \

View File

@ -576,21 +576,6 @@ TF_BUILTIN(StringCharCodeAt, StringBuiltinsAssembler) {
Return(result);
}
TF_BUILTIN(StringCodePointAt, StringBuiltinsAssembler) {
Node* receiver = Parameter(Descriptor::kReceiver);
Node* position = Parameter(Descriptor::kPosition);
// TODO(sigurds) Figure out if passing length as argument pays off.
TNode<IntPtrT> length = LoadStringLengthAsWord(receiver);
// Load the character code at the {position} from the {receiver}.
TNode<Int32T> code =
LoadSurrogatePairAt(receiver, length, position, UnicodeEncoding::UTF32);
// And return it as TaggedSigned value.
// TODO(turbofan): Allow builtins to return values untagged.
TNode<Smi> result = SmiFromWord32(code);
Return(result);
}
// -----------------------------------------------------------------------------
// ES6 section 21.1 String Objects

View File

@ -847,12 +847,6 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kSeqStringCharCodeAt:
result = LowerSeqStringCharCodeAt(node);
break;
case IrOpcode::kStringCodePointAt:
result = LowerStringCodePointAt(node);
break;
case IrOpcode::kSeqStringCodePointAt:
result = LowerSeqStringCharCodeAt(node);
break;
case IrOpcode::kStringToLowerCaseIntl:
result = LowerStringToLowerCaseIntl(node);
break;
@ -2693,25 +2687,19 @@ Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) {
__ NoContextConstant());
}
Node* EffectControlLinearizer::LowerStringCodePointAt(Node* node) {
Node* EffectControlLinearizer::LowerSeqStringCharCodeAt(Node* node) {
Node* receiver = node->InputAt(0);
Node* position = node->InputAt(1);
Callable const callable =
Builtins::CallableFor(isolate(), Builtins::kStringCodePointAt);
Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties,
MachineType::TaggedSigned());
return __ Call(desc, __ HeapConstant(callable.code()), receiver, position,
__ NoContextConstant());
}
Node* EffectControlLinearizer::LoadFromString(Node* receiver, Node* position,
Node* is_one_byte) {
auto one_byte_load = __ MakeLabel();
auto done = __ MakeLabel(MachineRepresentation::kWord32);
Node* map = __ LoadField(AccessBuilder::ForMap(), receiver);
Node* instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), map);
Node* is_one_byte = __ Word32Equal(
__ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)),
__ Int32Constant(kOneByteStringTag));
__ GotoIf(is_one_byte, &one_byte_load);
Node* two_byte_result = __ LoadElement(
AccessBuilder::ForSeqTwoByteStringCharacter(), receiver, position);
@ -2726,85 +2714,6 @@ Node* EffectControlLinearizer::LoadFromString(Node* receiver, Node* position,
return done.PhiAt(0);
}
Node* EffectControlLinearizer::LowerSeqStringCharCodeAt(Node* node) {
Node* receiver = node->InputAt(0);
Node* position = node->InputAt(1);
Node* map = __ LoadField(AccessBuilder::ForMap(), receiver);
Node* instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), map);
Node* is_one_byte = __ Word32Equal(
__ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)),
__ Int32Constant(kOneByteStringTag));
return LoadFromString(receiver, position, is_one_byte);
}
Node* EffectControlLinearizer::LowerSeqStringCodePointAt(
Node* node, UnicodeEncoding encoding) {
Node* receiver = node->InputAt(0);
Node* position = node->InputAt(1);
Node* map = __ LoadField(AccessBuilder::ForMap(), receiver);
Node* instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), map);
Node* is_one_byte = __ Word32Equal(
__ Word32And(instance_type, __ Int32Constant(kStringEncodingMask)),
__ Int32Constant(kOneByteStringTag));
Node* first_char_code = LoadFromString(receiver, position, is_one_byte);
auto return_result = __ MakeLabel(MachineRepresentation::kWord32);
// Check if first character code is outside of interval [0xD800, 0xDBFF].
Node* first_out =
__ Word32Equal(__ Word32And(first_char_code, __ Int32Constant(0xFC00)),
__ Int32Constant(0xD800));
// Return first character code.
__ GotoIf(first_out, &return_result, first_char_code);
// Check if position + 1 is still in range.
Node* length = __ LoadField(AccessBuilder::ForStringLength(), receiver);
Node* next_position = __ Int32Add(position, __ Int32Constant(1));
Node* next_position_in_range = __ Int32LessThan(next_position, length);
__ GotoIf(next_position_in_range, &return_result, first_char_code);
// Load second character code.
Node* second_char_code = LoadFromString(receiver, next_position, is_one_byte);
// Check if first character code is outside of interval [0xD800, 0xDBFF].
Node* second_out =
__ Word32Equal(__ Word32And(second_char_code, __ Int32Constant(0xFC00)),
__ Int32Constant(0xDC00));
__ GotoIfNot(second_out, &return_result, first_char_code);
Node* result;
switch (encoding) {
case UnicodeEncoding::UTF16:
result = __ Word32Or(
// Need to swap the order for big-endian platforms
#if V8_TARGET_BIG_ENDIAN
__ Word32Shl(first_char_code, __ Int32Constant(16)),
second_char_code));
#else
__ Word32Shl(second_char_code, __ Int32Constant(16)),
first_char_code);
#endif
break;
case UnicodeEncoding::UTF32: {
// Convert UTF16 surrogate pair into |word32| code point, encoded as
// UTF32.
Node* surrogate_offset =
__ Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00);
// (lead << 10) + trail + SURROGATE_OFFSET
result = __ Int32Add(__ Word32Shl(first_char_code, __ Int32Constant(10)),
__ Int32Add(second_char_code, surrogate_offset));
break;
}
}
__ Goto(&return_result, result);
__ Bind(&return_result);
return return_result.PhiAt(0);
}
Node* EffectControlLinearizer::LowerStringFromCharCode(Node* node) {
Node* value = node->InputAt(0);

View File

@ -118,8 +118,6 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* LowerStringCharAt(Node* node);
Node* LowerStringCharCodeAt(Node* node);
Node* LowerSeqStringCharCodeAt(Node* node);
Node* LowerStringCodePointAt(Node* node);
Node* LowerSeqStringCodePointAt(Node* node, UnicodeEncoding encoding);
Node* LowerStringToLowerCaseIntl(Node* node);
Node* LowerStringToUpperCaseIntl(Node* node);
Node* LowerStringFromCharCode(Node* node);
@ -181,7 +179,6 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* ChangeSmiToIntPtr(Node* value);
Node* ChangeSmiToInt32(Node* value);
Node* ObjectIsSmi(Node* value);
Node* LoadFromString(Node* receiver, Node* position, Node* is_one_byte);
Node* SmiMaxValueConstant();
Node* SmiShiftBitsConstant();

View File

@ -333,8 +333,6 @@
V(StringCharAt) \
V(StringCharCodeAt) \
V(SeqStringCharCodeAt) \
V(StringCodePointAt) \
V(SeqStringCodePointAt) \
V(StringFromCharCode) \
V(StringFromCodePoint) \
V(StringIndexOf) \

View File

@ -2341,22 +2341,6 @@ class RepresentationSelector {
}
return;
}
case IrOpcode::kStringCodePointAt: {
Type* string_type = TypeOf(node->InputAt(0));
if (string_type->Is(Type::SeqString())) {
VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
NodeProperties::ChangeOp(node,
simplified()->SeqStringCodePointAt());
}
} else {
// TODO(turbofan): Allow builtins to return untagged values.
VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
MachineRepresentation::kTaggedSigned);
}
return;
}
case IrOpcode::kStringFromCharCode: {
VisitUnop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kTaggedPointer);

View File

@ -657,8 +657,6 @@ bool operator==(CheckMinusZeroParameters const& lhs,
V(StringCharAt, Operator::kNoProperties, 2, 1) \
V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
V(SeqStringCharCodeAt, Operator::kNoProperties, 2, 1) \
V(StringCodePointAt, Operator::kNoProperties, 2, 1) \
V(SeqStringCodePointAt, Operator::kNoProperties, 2, 1) \
V(StringFromCharCode, Operator::kNoProperties, 1, 0) \
V(StringIndexOf, Operator::kNoProperties, 3, 0) \
V(StringLength, Operator::kNoProperties, 1, 0) \

View File

@ -503,8 +503,6 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* StringCharAt();
const Operator* StringCharCodeAt();
const Operator* SeqStringCharCodeAt();
const Operator* StringCodePointAt();
const Operator* SeqStringCodePointAt();
const Operator* StringFromCharCode();
const Operator* StringFromCodePoint(UnicodeEncoding encoding);
const Operator* StringIndexOf();

View File

@ -1948,14 +1948,6 @@ Type* Typer::Visitor::TypeSeqStringCharCodeAt(Node* node) {
return typer_->cache_.kUint16;
}
Type* Typer::Visitor::TypeStringCodePointAt(Node* node) {
return Type::Range(0.0, String::kMaxCodePoint, zone());
}
Type* Typer::Visitor::TypeSeqStringCodePointAt(Node* node) {
return Type::Range(0.0, String::kMaxCodePoint, zone());
}
Type* Typer::Visitor::TypeStringFromCharCode(Node* node) {
return TypeUnaryOp(node, StringFromCharCodeTyper);
}

View File

@ -1054,18 +1054,6 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
CheckValueInputIs(node, 1, Type::Unsigned32());
CheckTypeIs(node, Type::UnsignedSmall());
break;
case IrOpcode::kStringCodePointAt:
// (String, Unsigned32) -> UnsignedSmall
CheckValueInputIs(node, 0, Type::String());
CheckValueInputIs(node, 1, Type::Unsigned32());
CheckTypeIs(node, Type::UnsignedSmall());
break;
case IrOpcode::kSeqStringCodePointAt:
// (String, Unsigned32) -> UnsignedSmall
CheckValueInputIs(node, 0, Type::String());
CheckValueInputIs(node, 1, Type::Unsigned32());
CheckTypeIs(node, Type::UnsignedSmall());
break;
case IrOpcode::kStringFromCharCode:
// Number -> String
CheckValueInputIs(node, 0, Type::Number());

View File

@ -269,7 +269,21 @@ void StoreNamedTransitionDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(len, registers);
}
void StringAtDescriptor::InitializePlatformIndependent(
void StringCharAtDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kReceiver, kPosition
MachineType machine_types[] = {MachineType::AnyTagged(),
MachineType::IntPtr()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void StringCharAtDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
void StringCharCodeAtDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kReceiver, kPosition
// TODO(turbofan): Allow builtins to return untagged values.
@ -279,7 +293,7 @@ void StringAtDescriptor::InitializePlatformIndependent(
machine_types);
}
void StringAtDescriptor::InitializePlatformSpecific(
void StringCharCodeAtDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}

View File

@ -62,7 +62,8 @@ class PlatformInterfaceDescriptor;
V(Compare) \
V(BinaryOp) \
V(StringAdd) \
V(StringAt) \
V(StringCharAt) \
V(StringCharCodeAt) \
V(ForInPrepare) \
V(GetProperty) \
V(ArgumentAdaptor) \
@ -761,12 +762,17 @@ class StringAddDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
};
// This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
// as they all have the same interface.
class StringAtDescriptor final : public CallInterfaceDescriptor {
class StringCharAtDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kPosition)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StringAtDescriptor,
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StringCharAtDescriptor,
CallInterfaceDescriptor)
};
class StringCharCodeAtDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kPosition)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StringCharCodeAtDescriptor,
CallInterfaceDescriptor)
};