| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index 050d6ce0873211d55f179b50b1f4c1e88ef39b67..5133f6e718e23880c02144d1a45b7db959c2e2d7 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -8,6 +8,7 @@
|
|
|
| #include "src/base/bits.h"
|
| #include "src/code-factory.h"
|
| +#include "src/compiler/access-builder.h"
|
| #include "src/compiler/common-operator.h"
|
| #include "src/compiler/diamond.h"
|
| #include "src/compiler/linkage.h"
|
| @@ -869,12 +870,7 @@ class RepresentationSelector {
|
| ProcessInput(node, 0, kMachAnyTagged);
|
| SetOutput(node, kRepBit | kTypeBool);
|
| if (lower()) {
|
| - Node* is_tagged = jsgraph_->graph()->NewNode(
|
| - jsgraph_->machine()->WordAnd(), node->InputAt(0),
|
| - jsgraph_->IntPtrConstant(kSmiTagMask));
|
| - Node* is_smi = jsgraph_->graph()->NewNode(
|
| - jsgraph_->machine()->WordEqual(), is_tagged,
|
| - jsgraph_->IntPtrConstant(kSmiTag));
|
| + Node* is_smi = lowering->IsSmi(node->InputAt(0));
|
| DeferReplacement(node, is_smi);
|
| }
|
| break;
|
| @@ -883,12 +879,7 @@ class RepresentationSelector {
|
| ProcessInput(node, 0, kMachAnyTagged);
|
| SetOutput(node, kRepBit | kTypeBool);
|
| if (lower()) {
|
| - Node* is_tagged = jsgraph_->graph()->NewNode(
|
| - jsgraph_->machine()->WordAnd(), node->InputAt(0),
|
| - jsgraph_->IntPtrConstant(kSmiTagMask));
|
| - Node* is_smi = jsgraph_->graph()->NewNode(
|
| - jsgraph_->machine()->WordEqual(), is_tagged,
|
| - jsgraph_->IntPtrConstant(kSmiTag));
|
| + Node* is_smi = lowering->IsSmi(node->InputAt(0));
|
| Node* is_non_neg = jsgraph_->graph()->NewNode(
|
| jsgraph_->machine()->IntLessThanOrEqual(),
|
| jsgraph_->IntPtrConstant(0), node->InputAt(0));
|
| @@ -898,6 +889,12 @@ class RepresentationSelector {
|
| }
|
| break;
|
| }
|
| + case IrOpcode::kCheckMaps: {
|
| + // TODO(titzer): don't require tagged input to CheckMaps.
|
| + VisitInputs(node);
|
| + if (lower()) lowering->DoCheckMaps(node);
|
| + break;
|
| + }
|
|
|
| //------------------------------------------------------------------
|
| // Machine-level operators.
|
| @@ -1120,6 +1117,16 @@ Node* SimplifiedLowering::IsTagged(Node* node) {
|
| }
|
|
|
|
|
| +Node* SimplifiedLowering::IsSmi(Node* node) {
|
| + Node* is_tagged = jsgraph_->graph()->NewNode(
|
| + machine()->WordAnd(), node, jsgraph()->IntPtrConstant(kSmiTagMask));
|
| + Node* is_smi =
|
| + jsgraph_->graph()->NewNode(jsgraph()->machine()->WordEqual(), is_tagged,
|
| + jsgraph()->IntPtrConstant(kSmiTag));
|
| + return is_smi;
|
| +}
|
| +
|
| +
|
| void SimplifiedLowering::LowerAllNodes() {
|
| SimplifiedOperatorBuilder simplified(graph()->zone());
|
| RepresentationChanger changer(jsgraph(), &simplified, jsgraph()->isolate());
|
| @@ -1615,6 +1622,62 @@ void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
|
| node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
|
| }
|
|
|
| +
|
| +void SimplifiedLowering::DoCheckMaps(Node* node) {
|
| + bool smi_check = true;
|
| +
|
| + Node* receiver = node->InputAt(0);
|
| + Node* control = NodeProperties::GetControlInput(node);
|
| + Node* effect = NodeProperties::GetEffectInput(node);
|
| + int map_count = OpParameter<int32_t>(node->op());
|
| + Node* frame_state = node->InputAt(1 + map_count);
|
| +
|
| + if (smi_check) {
|
| + // Inline a smi check first.
|
| + Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse),
|
| + IsSmi(receiver), control);
|
| + Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi);
|
| + AddDeoptimize(frame_state, effect, if_smi);
|
| + control = graph()->NewNode(common()->IfFalse(), branch_smi);
|
| + }
|
| +
|
| + // Add checks against the maps.
|
| + NodeVector checks(zone());
|
| + checks.reserve(map_count);
|
| + FieldAccess map_access = AccessBuilder::ForMap();
|
| + Node* offset =
|
| + jsgraph()->IntPtrConstant(map_access.offset - map_access.tag());
|
| + Node* receiver_map =
|
| + graph()->NewNode(machine()->Load(map_access.machine_type), receiver,
|
| + offset, effect, control);
|
| + for (int i = 1; i <= map_count; i++) {
|
| + Node* map = node->InputAt(i);
|
| + Node* cmp = graph()->NewNode(machine()->WordEqual(), receiver_map, map);
|
| + Node* branch =
|
| + graph()->NewNode(common()->Branch(BranchHint::kTrue), cmp, control);
|
| + Node* fail = graph()->NewNode(common()->IfFalse(), branch);
|
| + AddDeoptimize(frame_state, effect, fail);
|
| + Node* success = graph()->NewNode(common()->IfTrue(), branch);
|
| + checks.push_back(success);
|
| + }
|
| +
|
| + // Create a merge of the checks if necessary.
|
| + Node* success =
|
| + checks.size() == 1
|
| + ? checks[0]
|
| + : graph()->NewNode(common()->Merge(map_count), map_count, &checks[0]);
|
| +
|
| + node->ReplaceUses(success);
|
| +}
|
| +
|
| +
|
| +void SimplifiedLowering::AddDeoptimize(Node* frame_state_before, Node* effect,
|
| + Node* control) {
|
| + Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before,
|
| + effect, control);
|
| + NodeProperties::MergeControlToEnd(graph(), common(), deopt);
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|