Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Unified Diff: src/compiler/effect-control-linearizer.cc

Issue 2600443002: [turbofan] Lower StringCharCodeAt to a dedicated builtin. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-factory.cc ('k') | src/compiler/simplified-lowering.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/effect-control-linearizer.cc
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
index 6b72b14249e1f5a8d5c39b92a952509359230c08..ae360fa23e482c9e0dab21bd2fa4547662a4a254 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -2247,268 +2247,18 @@ EffectControlLinearizer::LowerStringCharAt(Node* node, Node* effect,
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect,
Node* control) {
- Node* subject = node->InputAt(0);
- Node* index = node->InputAt(1);
-
- // We may need to loop several times for ConsString/SlicedString {subject}s.
- Node* loop =
- graph()->NewNode(common()->Loop(4), control, control, control, control);
- Node* lsubject =
- graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 4),
- subject, subject, subject, subject, loop);
- Node* lindex =
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 4), index,
- index, index, index, loop);
- Node* leffect = graph()->NewNode(common()->EffectPhi(4), effect, effect,
- effect, effect, loop);
-
- control = loop;
- effect = leffect;
-
- // Determine the instance type of {lsubject}.
- Node* lsubject_map = effect =
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
- lsubject, effect, control);
- Node* lsubject_instance_type = effect = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
- lsubject_map, effect, control);
-
- // Check if {lsubject} is a SeqString.
- Node* check0 = graph()->NewNode(
- machine()->Word32Equal(),
- graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
- jsgraph()->Int32Constant(kStringRepresentationMask)),
- jsgraph()->Int32Constant(kSeqStringTag));
- Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
-
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
- Node* etrue0 = effect;
- Node* vtrue0;
- {
- // Check if the {lsubject} is a TwoByteSeqString or a OneByteSeqString.
- Node* check1 = graph()->NewNode(
- machine()->Word32Equal(),
- graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
- jsgraph()->Int32Constant(kStringEncodingMask)),
- jsgraph()->Int32Constant(kTwoByteStringTag));
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
-
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* etrue1 = etrue0;
- Node* vtrue1 = etrue1 =
- graph()->NewNode(simplified()->LoadElement(
- AccessBuilder::ForSeqTwoByteStringCharacter()),
- lsubject, lindex, etrue1, if_true1);
-
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* efalse1 = etrue0;
- Node* vfalse1 = efalse1 =
- graph()->NewNode(simplified()->LoadElement(
- AccessBuilder::ForSeqOneByteStringCharacter()),
- lsubject, lindex, efalse1, if_false1);
-
- if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
- etrue0 =
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
- vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
- vtrue1, vfalse1, if_true0);
- }
-
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
- Node* efalse0 = effect;
- Node* vfalse0;
- {
- // Check if the {lsubject} is a ConsString.
- Node* check1 = graph()->NewNode(
- machine()->Word32Equal(),
- graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
- jsgraph()->Int32Constant(kStringRepresentationMask)),
- jsgraph()->Int32Constant(kConsStringTag));
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
-
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
- Node* etrue1 = efalse0;
- {
- // Load the right hand side of the {lsubject} ConsString.
- Node* lsubject_second = etrue1 = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForConsStringSecond()),
- lsubject, etrue1, if_true1);
-
- // Check whether the right hand side is the empty string (i.e. if
- // this is really a flat string in a cons string). If that is not
- // the case we flatten the string first.
- Node* check2 = graph()->NewNode(machine()->WordEqual(), lsubject_second,
- jsgraph()->EmptyStringConstant());
- Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
- check2, if_true1);
-
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
- Node* etrue2 = etrue1;
- Node* vtrue2 = etrue2 = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForConsStringFirst()),
- lsubject, etrue2, if_true2);
-
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
- Node* efalse2 = etrue1;
- Node* vfalse2;
- {
- // Flatten the {lsubject} ConsString first.
- Operator::Properties properties =
- Operator::kNoDeopt | Operator::kNoThrow;
- Runtime::FunctionId id = Runtime::kFlattenString;
- CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
- graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags);
- vfalse2 = efalse2 = graph()->NewNode(
- common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
- jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
- jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(),
- efalse2, if_false2);
- }
-
- // Retry the {loop} with the new subject.
- loop->ReplaceInput(1, if_true2);
- lindex->ReplaceInput(1, lindex);
- leffect->ReplaceInput(1, etrue2);
- lsubject->ReplaceInput(1, vtrue2);
- loop->ReplaceInput(2, if_false2);
- lindex->ReplaceInput(2, lindex);
- leffect->ReplaceInput(2, efalse2);
- lsubject->ReplaceInput(2, vfalse2);
- }
-
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
- Node* efalse1 = efalse0;
- Node* vfalse1;
- {
- // Check if the {lsubject} is an ExternalString.
- Node* check2 = graph()->NewNode(
- machine()->Word32Equal(),
- graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
- jsgraph()->Int32Constant(kStringRepresentationMask)),
- jsgraph()->Int32Constant(kExternalStringTag));
- Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
- check2, if_false1);
-
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
- Node* etrue2 = efalse1;
- Node* vtrue2;
- {
- // Check if the {lsubject} is a short external string.
- Node* check3 = graph()->NewNode(
- machine()->Word32Equal(),
- graph()->NewNode(
- machine()->Word32And(), lsubject_instance_type,
- jsgraph()->Int32Constant(kShortExternalStringMask)),
- jsgraph()->Int32Constant(0));
- Node* branch3 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
- check3, if_true2);
-
- Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3);
- Node* etrue3 = etrue2;
- Node* vtrue3;
- {
- // Load the actual resource data from the {lsubject}.
- Node* lsubject_resource_data = etrue3 = graph()->NewNode(
- simplified()->LoadField(
- AccessBuilder::ForExternalStringResourceData()),
- lsubject, etrue3, if_true3);
-
- // Check if the {lsubject} is a TwoByteExternalString or a
- // OneByteExternalString.
- Node* check4 = graph()->NewNode(
- machine()->Word32Equal(),
- graph()->NewNode(machine()->Word32And(), lsubject_instance_type,
- jsgraph()->Int32Constant(kStringEncodingMask)),
- jsgraph()->Int32Constant(kTwoByteStringTag));
- Node* branch4 =
- graph()->NewNode(common()->Branch(), check4, if_true3);
-
- Node* if_true4 = graph()->NewNode(common()->IfTrue(), branch4);
- Node* etrue4 = etrue3;
- Node* vtrue4 = etrue4 = graph()->NewNode(
- simplified()->LoadElement(
- AccessBuilder::ForExternalTwoByteStringCharacter()),
- lsubject_resource_data, lindex, etrue4, if_true4);
-
- Node* if_false4 = graph()->NewNode(common()->IfFalse(), branch4);
- Node* efalse4 = etrue3;
- Node* vfalse4 = efalse4 = graph()->NewNode(
- simplified()->LoadElement(
- AccessBuilder::ForExternalOneByteStringCharacter()),
- lsubject_resource_data, lindex, efalse4, if_false4);
-
- if_true3 = graph()->NewNode(common()->Merge(2), if_true4, if_false4);
- etrue3 = graph()->NewNode(common()->EffectPhi(2), etrue4, efalse4,
- if_true3);
- vtrue3 =
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
- vtrue4, vfalse4, if_true3);
- }
-
- Node* if_false3 = graph()->NewNode(common()->IfFalse(), branch3);
- Node* efalse3 = etrue2;
- Node* vfalse3;
- {
- // The {lsubject} might be compressed, call the runtime.
- Operator::Properties properties =
- Operator::kNoDeopt | Operator::kNoThrow;
- Runtime::FunctionId id = Runtime::kExternalStringGetChar;
- CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor(
- graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags);
- vfalse3 = efalse3 = graph()->NewNode(
- common()->Call(desc), jsgraph()->CEntryStubConstant(1), lsubject,
- ChangeInt32ToSmi(lindex),
- jsgraph()->ExternalConstant(ExternalReference(id, isolate())),
- jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(),
- efalse3, if_false3);
- vfalse3 = ChangeSmiToInt32(vfalse3);
- }
-
- if_true2 = graph()->NewNode(common()->Merge(2), if_true3, if_false3);
- etrue2 =
- graph()->NewNode(common()->EffectPhi(2), etrue3, efalse3, if_true2);
- vtrue2 =
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
- vtrue3, vfalse3, if_true2);
- }
-
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
- Node* efalse2 = efalse1;
- {
- // The {lsubject} is a SlicedString, continue with its parent.
- Node* lsubject_parent = efalse2 = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForSlicedStringParent()),
- lsubject, efalse2, if_false2);
- Node* lsubject_offset = efalse2 = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForSlicedStringOffset()),
- lsubject, efalse2, if_false2);
- Node* lsubject_index = graph()->NewNode(
- machine()->Int32Add(), lindex, ChangeSmiToInt32(lsubject_offset));
-
- // Retry the {loop} with the parent subject.
- loop->ReplaceInput(3, if_false2);
- leffect->ReplaceInput(3, efalse2);
- lindex->ReplaceInput(3, lsubject_index);
- lsubject->ReplaceInput(3, lsubject_parent);
- }
-
- if_false1 = if_true2;
- efalse1 = etrue2;
- vfalse1 = vtrue2;
- }
-
- if_false0 = if_false1;
- efalse0 = efalse1;
- vfalse0 = vfalse1;
- }
-
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
- Node* value =
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
- vfalse0, control);
-
- return ValueEffectControl(value, effect, control);
+ Callable const callable = CodeFactory::StringCharCodeAt(isolate());
+ 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());
+ node->InsertInput(graph()->zone(), 0,
+ jsgraph()->HeapConstant(callable.code()));
+ node->InsertInput(graph()->zone(), 3, jsgraph()->NoContextConstant());
+ node->InsertInput(graph()->zone(), 4, effect);
+ NodeProperties::ChangeOp(node, common()->Call(desc));
+ return ValueEffectControl(node, node, control);
}
EffectControlLinearizer::ValueEffectControl
« no previous file with comments | « src/code-factory.cc ('k') | src/compiler/simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698