js-typed-lowering.cc revision f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/compiler/js-typed-lowering.h" 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/builtins/builtins-utils.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/code-factory.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compilation-dependencies.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/access-builder.h" 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/js-graph.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/linkage.h" 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-matchers.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/operator-properties.h" 16f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/type-cache.h" 17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/types.h" 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class to simplify the process of reducing a single binop node with a 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// JSOperator. This class manages the rewriting of context, control, and effect 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// dependencies during lowering of a binop and contains numerous helper 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// functions for matching the types of inputs to an operation. 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass JSBinopReduction final { 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction(JSTypedLowering* lowering, Node* node) 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : lowering_(lowering), node_(node) {} 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool GetBinaryNumberOperationHint(NumberOperationHint* hint) { 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_NE(0, node_->op()->ControlOutputCount()); 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op())); 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (BinaryOperationHintOf(node_->op())) { 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case BinaryOperationHint::kSignedSmall: 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kSignedSmall; 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case BinaryOperationHint::kSigned32: 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kSigned32; 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case BinaryOperationHint::kNumberOrOddball: 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kNumberOrOddball; 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case BinaryOperationHint::kAny: 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case BinaryOperationHint::kNone: 49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case BinaryOperationHint::kString: 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool GetCompareNumberOperationHint(NumberOperationHint* hint) { 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (CompareOperationHintOf(node_->op())) { 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kSignedSmall: 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kSignedSmall; 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kNumber: 64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kNumber; 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kNumberOrOddball: 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kNumberOrOddball; 68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kAny: 70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kNone: 71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 7613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 77f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if a string addition will definitely result in creating a ConsString, 78f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // i.e. if the combined length of the resulting string exceeds the ConsString 79f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // minimum length. 80f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool ShouldCreateConsString() { 81f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); 82f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (BothInputsAre(Type::String()) || 83f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && 84f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { 85f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (right_type()->IsConstant() && 86f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch right_type()->AsConstant()->Value()->IsString()) { 87f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String> right_string = 88f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String>::cast(right_type()->AsConstant()->Value()); 89f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (right_string->length() >= ConsString::kMinLength) return true; 90f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (left_type()->IsConstant() && 92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch left_type()->AsConstant()->Value()->IsString()) { 93f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String> left_string = 94f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String>::cast(left_type()->AsConstant()->Value()); 95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (left_string->length() >= ConsString::kMinLength) { 96f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The invariant for ConsString requires the left hand side to be 97f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // a sequential or external string if the right hand side is the 98f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // empty string. Since we don't know anything about the right hand 99f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // side here, we must ensure that the left hand side satisfy the 100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // constraints independent of the right hand side. 101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return left_string->IsSeqString() || left_string->IsExternalString(); 102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ConvertInputsToNumber() { 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // To convert the inputs to numbers, we have to provide frame states 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // for lazy bailouts in the ToNumber conversions. 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We use a little hack here: we take the frame state before the binary 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // operation and use it to construct the frame states for the conversion 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // so that after the deoptimization, the binary operation IC gets 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // already converted values from full code. This way we are sure that we 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // will not re-do any of the side effects. 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_input = nullptr; 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right_input = nullptr; 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool left_is_primitive = left_type()->Is(Type::PlainPrimitive()); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool right_is_primitive = right_type()->Is(Type::PlainPrimitive()); 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool handles_exception = NodeProperties::IsExceptionalCall(node_); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!left_is_primitive && !right_is_primitive && handles_exception) { 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ConvertBothInputsToNumber(&left_input, &right_input); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_input = left_is_primitive 12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ? ConvertPlainPrimitiveToNumber(left()) 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ConvertSingleInputToNumber( 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch left(), CreateFrameStateForLeftInput()); 130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch right_input = 131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch right_is_primitive 132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? ConvertPlainPrimitiveToNumber(right()) 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : ConvertSingleInputToNumber( 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch right(), CreateFrameStateForRightInput(left_input)); 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node_->ReplaceInput(0, left_input); 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node_->ReplaceInput(1, right_input); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ConvertInputsToUI32(Signedness left_signedness, 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Signedness right_signedness) { 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SwapInputs() { 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* l = left(); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* r = right(); 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_->ReplaceInput(0, r); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_->ReplaceInput(1, l); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove all effect and control inputs and outputs to this node and change 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the pure operator {op}, possibly inserting a boolean inversion. 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction ChangeToPureOperator(const Operator* op, bool invert = false, 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Type* type = Type::Any()) { 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(0, op->EffectInputCount()); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(0, op->ControlInputCount()); 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(2, op->ValueInputCount()); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Remove the effects from the node, and update its effect/control usages. 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node_->op()->EffectInputCount() > 0) { 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lowering_->RelaxEffectsAndControls(node_); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove the inputs corresponding to context, effect, and control. 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeProperties::RemoveNonValueInputs(node_); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finally, update the operator to the new one. 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node_, op); 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(jarin): Replace the explicit typing hack with a call to some method 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // that encapsulates changing the operator and re-typing. 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* node_type = NodeProperties::GetType(node_); 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone())); 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (invert) { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Insert an boolean not to invert the value. 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_->ReplaceUses(value); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note: ReplaceUses() smashes all uses, so smash it back here. 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value->ReplaceInput(0, node_); 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return lowering_->Replace(value); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return lowering_->Changed(node_); 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Reduction ChangeToSpeculativeOperator(const Operator* op, bool invert, 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Type* upper_bound) { 19013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, op->EffectInputCount()); 19113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, op->EffectOutputCount()); 19213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 19313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, op->ControlInputCount()); 19413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(0, op->ControlOutputCount()); 19513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); 19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(2, op->ValueInputCount()); 19713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, node_->op()->EffectInputCount()); 19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, node_->op()->ControlInputCount()); 20113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(2, node_->op()->ValueInputCount()); 20213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 20313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Reconnect the control output to bypass the IfSuccess node and 20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // possibly disconnect from the IfException node. 20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (Edge edge : node_->use_edges()) { 20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* const user = edge.from(); 20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!user->IsDead()); 20813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (NodeProperties::IsControlEdge(edge)) { 20913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (user->opcode() == IrOpcode::kIfSuccess) { 21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch user->ReplaceUses(NodeProperties::GetControlInput(node_)); 21113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch user->Kill(); 21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(user->opcode(), IrOpcode::kIfException); 21413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch edge.UpdateTo(jsgraph()->Dead()); 21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 21613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 21713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 21813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Remove the frame state and the context. 220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (OperatorProperties::HasFrameStateInput(node_->op())) { 221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); 222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 22313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); 22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 22513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::ChangeOp(node_, op); 22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 22713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Update the type to number. 22813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Type* node_type = NodeProperties::GetType(node_); 22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::SetType(node_, 23013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Type::Intersect(node_type, upper_bound, zone())); 23113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (invert) { 233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Insert an boolean not to invert the value. 234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); 235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node_->ReplaceUses(value); 236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Note: ReplaceUses() smashes all uses, so smash it back here. 237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch value->ReplaceInput(0, node_); 238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return lowering_->Replace(value); 239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return lowering_->Changed(node_); 24113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 24213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction ChangeToPureOperator(const Operator* op, Type* type) { 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ChangeToPureOperator(op, false, type); 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Reduction ChangeToSpeculativeOperator(const Operator* op, Type* type) { 248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ChangeToSpeculativeOperator(op, false, type); 249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* NumberOp() { 252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node_->opcode()) { 253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSAdd: 254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberAdd(); 255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSSubtract: 256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberSubtract(); 257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSMultiply: 258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberMultiply(); 259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSDivide: 260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberDivide(); 261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSModulus: 262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberModulus(); 263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseAnd: 264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberBitwiseAnd(); 265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseOr: 266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberBitwiseOr(); 267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseXor: 268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberBitwiseXor(); 269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftLeft: 270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberShiftLeft(); 271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftRight: 272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberShiftRight(); 273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftRightLogical: 274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberShiftRightLogical(); 275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return nullptr; 280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* SpeculativeNumberOp(NumberOperationHint hint) { 283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node_->opcode()) { 284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSAdd: 285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberAdd(hint); 286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSSubtract: 287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberSubtract(hint); 288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSMultiply: 289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberMultiply(hint); 290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSDivide: 291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberDivide(hint); 292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSModulus: 293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberModulus(hint); 294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseAnd: 295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberBitwiseAnd(hint); 296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseOr: 297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberBitwiseOr(hint); 298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseXor: 299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberBitwiseXor(hint); 300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftLeft: 301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberShiftLeft(hint); 302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftRight: 303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberShiftRight(hint); 304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftRightLogical: 305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->SpeculativeNumberShiftRightLogical(hint); 306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return nullptr; 311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool LeftInputIs(Type* t) { return left_type()->Is(t); } 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool RightInputIs(Type* t) { return right_type()->Is(t); } 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); } 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool OneInputCannotBe(Type* t) { 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !left_type()->Maybe(t) || !right_type()->Maybe(t); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool NeitherInputCanBe(Type* t) { 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !left_type()->Maybe(t) && !right_type()->Maybe(t); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* effect() { return NodeProperties::GetEffectInput(node_); } 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* control() { return NodeProperties::GetControlInput(node_); } 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* context() { return NodeProperties::GetContextInput(node_); } 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* left() { return NodeProperties::GetValueInput(node_, 0); } 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* right() { return NodeProperties::GetValueInput(node_, 1); } 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* left_type() { return NodeProperties::GetType(node_->InputAt(0)); } 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* right_type() { return NodeProperties::GetType(node_->InputAt(1)); } 336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Type* type() { return NodeProperties::GetType(node_); } 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); } 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Graph* graph() const { return lowering_->graph(); } 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSGraph* jsgraph() { return lowering_->jsgraph(); } 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSOperatorBuilder* javascript() { return lowering_->javascript(); } 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CommonOperatorBuilder* common() { return jsgraph()->common(); } 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Zone* zone() const { return graph()->zone(); } 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSTypedLowering* lowering_; // The containing lowering instance. 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* node_; // The original node. 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* CreateFrameStateForLeftInput() { 350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Deoptimization is disabled => return dummy frame state instead. 351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* dummy_state = NodeProperties::GetFrameStateInput(node_); 352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); 353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return dummy_state; 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* CreateFrameStateForRightInput(Node* converted_left) { 357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Deoptimization is disabled => return dummy frame state instead. 358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* dummy_state = NodeProperties::GetFrameStateInput(node_); 359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); 360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return dummy_state; 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 36313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* ConvertPlainPrimitiveToNumber(Node* node) { 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Avoid inserting too many eager ToNumber() operations. 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Reduction const reduction = lowering_->ReduceJSToNumberInput(node); 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (reduction.Changed()) return reduction.replacement(); 36813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (NodeProperties::GetType(node)->Is(Type::Number())) { 369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return node; 370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 37113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), node); 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) { 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(), 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_state, effect(), control()); 378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* const if_success = graph()->NewNode(common()->IfSuccess(), n); 379bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NodeProperties::ReplaceControlInput(node_, if_success); 380bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NodeProperties::ReplaceUses(node_, node_, node_, node_, n); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch update_effect(n); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return n; 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ConvertBothInputsToNumber(Node** left_result, Node** right_result) { 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* projections[2]; 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find {IfSuccess} and {IfException} continuations of the operation. 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::CollectControlProjections(node_, projections, 2); 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_exception = projections[1]; 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_success = projections[0]; 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert two ToNumber() operations that both potentially throw. 394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* left_state = CreateFrameStateForLeftInput(); 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_conv = 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ToNumber(), left(), context(), 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_state, effect(), control()); 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv); 399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* right_state = CreateFrameStateForRightInput(left_conv); 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right_conv = 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ToNumber(), right(), context(), 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right_state, left_conv, left_success); 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_exception = 404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->IfException(), left_conv, left_conv); 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right_exception = 406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->IfException(), right_conv, right_conv); 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceControlInput(if_success, right_conv); 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch update_effect(right_conv); 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wire conversions to existing {IfException} continuation. 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_merge = if_exception; 412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_value = 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_exception, right_exception, exception_merge); 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_effect = 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->EffectPhi(2), left_exception, 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right_exception, exception_merge); 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (Edge edge : exception_merge->use_edges()) { 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect); 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value); 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::RemoveType(exception_merge); 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exception_merge->ReplaceInput(0, left_exception); 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exception_merge->ReplaceInput(1, right_exception); 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(exception_merge, common()->Merge(2)); 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *left_result = left_conv; 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *right_result = right_conv; 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* ConvertToUI32(Node* node, Signedness signedness) { 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Avoid introducing too many eager NumberToXXnt32() operations. 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* type = NodeProperties::GetType(node); 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (signedness == kSigned) { 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!type->Is(Type::Signed32())) { 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node = graph()->NewNode(simplified()->NumberToInt32(), node); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(kUnsigned, signedness); 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!type->Is(Type::Unsigned32())) { 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node = graph()->NewNode(simplified()->NumberToUint32(), node); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return node; 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void update_effect(Node* effect) { 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeProperties::ReplaceEffectInput(node_, effect); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(turbofan): js-typed-lowering improvements possible 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - immediately put in type bounds for all new nodes 455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - relax effects from generic but not-side-effecting operations 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochJSTypedLowering::JSTypedLowering(Editor* editor, 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationDependencies* dependencies, 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Flags flags, JSGraph* jsgraph, Zone* zone) 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AdvancedReducer(editor), 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dependencies_(dependencies), 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags_(flags), 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph_(jsgraph), 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch the_hole_type_( 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type::Constant(factory()->the_hole_value(), graph()->zone())), 467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type_cache_(TypeCache::Get()) { 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double min = kMinInt / (1 << k); 470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double max = kMaxInt / (1 << k); 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSAdd(Node* node) { 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.GetBinaryNumberOperationHint(&hint)) { 479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (hint == NumberOperationHint::kNumberOrOddball && 480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::PlainPrimitive()) && 481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.NeitherInputCanBe(Type::StringOrReceiver())) { 482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) 483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); 485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 48613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return r.ChangeToSpeculativeOperator( 487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->SpeculativeNumberAdd(hint), Type::Number()); 48813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 48913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (r.BothInputsAre(Type::Number())) { 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSAdd(x:number, y:number) => NumberAdd(x, y) 491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 49213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if ((r.BothInputsAre(Type::PlainPrimitive()) || 495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) && 496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.NeitherInputCanBe(Type::StringOrReceiver())) { 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) 498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 501bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (r.OneInputIs(Type::String())) { 502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (r.ShouldCreateConsString()) { 503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ReduceCreateConsString(node); 504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 505bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch StringAddFlags flags = STRING_ADD_CHECK_NONE; 506bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!r.LeftInputIs(Type::String())) { 507bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch flags = STRING_ADD_CONVERT_LEFT; 508bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (!r.RightInputIs(Type::String())) { 509bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch flags = STRING_ADD_CONVERT_RIGHT; 510bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 511bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // JSAdd(x:string, y) => CallStub[StringAdd](x, y) 512bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // JSAdd(x, y:string) => CallStub[StringAdd](x, y) 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable const callable = 514bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CodeFactory::StringAdd(isolate(), flags, NOT_TENURED); 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::kNeedsFrameState, node->op()->properties()); 518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, common()->Call(desc)); 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NoChange(); 525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceNumberBinop(Node* node) { 528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSBinopReduction r(this, node); 529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.GetBinaryNumberOperationHint(&hint)) { 531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (hint == NumberOperationHint::kNumberOrOddball && 532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::PlainPrimitive())) { 533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), Type::Number()); 535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator(r.SpeculativeNumberOp(hint), 537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Type::Number()); 538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::PlainPrimitive()) || 540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) { 541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), Type::Number()); 54313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NoChange(); 545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceInt32Binop(Node* node) { 54813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch JSBinopReduction r(this, node); 549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.GetBinaryNumberOperationHint(&hint)) { 551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator(r.SpeculativeNumberOp(hint), 552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Type::Signed32()); 55313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::PlainPrimitive()) || 555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) { 556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToUI32(kSigned, kSigned); 558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), Type::Signed32()); 55913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 56113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 56213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceUI32Shift(Node* node, Signedness signedness) { 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.GetBinaryNumberOperationHint(&hint)) { 56713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return r.ChangeToSpeculativeOperator( 568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.SpeculativeNumberOp(hint), 569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch signedness == kUnsigned ? Type::Unsigned32() : Type::Signed32()); 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::PlainPrimitive()) || 572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) { 573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToUI32(signedness, kUnsigned); 575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), signedness == kUnsigned 576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? Type::Unsigned32() 577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : Type::Signed32()); 578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochReduction JSTypedLowering::ReduceCreateConsString(Node* node) { 583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* first = NodeProperties::GetValueInput(node, 0); 584f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* second = NodeProperties::GetValueInput(node, 1); 585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Make sure {first} is actually a String. 591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type* first_type = NodeProperties::GetType(first); 592f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!first_type->Is(Type::String())) { 593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first = effect = 594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->CheckString(), first, effect, control); 595f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first_type = NodeProperties::GetType(first); 596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 598f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Make sure {second} is actually a String. 599f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type* second_type = NodeProperties::GetType(second); 600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!second_type->Is(Type::String())) { 601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second = effect = 602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->CheckString(), second, effect, control); 603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second_type = NodeProperties::GetType(second); 604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Determine the {first} length. 607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* first_length = 608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first_type->IsConstant() 609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ? jsgraph()->Constant( 610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String>::cast(first_type->AsConstant()->Value()) 611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ->length()) 612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : effect = graph()->NewNode( 613f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForStringLength()), 614f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first, effect, control); 615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Determine the {second} length. 617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* second_length = 618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second_type->IsConstant() 619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ? jsgraph()->Constant( 620f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<String>::cast(second_type->AsConstant()->Value()) 621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ->length()) 622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : effect = graph()->NewNode( 623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForStringLength()), 624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second, effect, control); 625f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 626f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Compute the resulting length. 627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* length = 628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->NumberAdd(), first_length, second_length); 629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we would overflow the allowed maximum string length. 631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length, 632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(String::kMaxLength)); 633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch = 634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* efalse = effect; 637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 638f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Throw a RangeError in case of overflow. 639f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vfalse = efalse = graph()->NewNode( 640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch javascript()->CallRuntime(Runtime::kThrowInvalidStringLength), context, 641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch frame_state, efalse, if_false); 642f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_false = graph()->NewNode(common()->IfSuccess(), vfalse); 643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false); 644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(bmeurer): This should be on the AdvancedReducer somehow. 645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::MergeControlToEnd(graph(), common(), if_false); 646f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Revisit(graph()->end()); 647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Update potential {IfException} uses of {node} to point to the 649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // %ThrowInvalidStringLength runtime call node instead. 650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (Edge edge : node->use_edges()) { 651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (edge.from()->opcode() == IrOpcode::kIfException) { 652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(NodeProperties::IsControlEdge(edge) || 653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::IsEffectEdge(edge)); 654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch edge.UpdateTo(vfalse); 655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Revisit(edge.from()); 656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfTrue(), branch); 660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Figure out the map for the resulting ConsString. 662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(turbofan): We currently just use the cons_string_map here for 663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // the sake of simplicity; we could also try to be smarter here and 664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // use the one_byte_cons_string_map instead when the resulting ConsString 665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // contains only one byte characters. 666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map()); 667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Allocate the resulting ConsString. 669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->BeginRegion(RegionObservability::kNotObservable), effect); 671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* value = effect = 672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->Allocate(NOT_TENURED), 673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(ConsString::kSize), effect, control); 674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::SetType(value, Type::OtherString()); 675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), 676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch value, value_map, effect, control); 677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForNameHashField()), value, 679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Uint32Constant(Name::kEmptyHashField), effect, control); 680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForStringLength()), value, length, 682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForConsStringFirst()), value, 685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first, effect, control); 686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForConsStringSecond()), value, 688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second, effect, control); 689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Morph the {node} into a {FinishRegion}. 691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ReplaceWithValue(node, node, node, control); 692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(0, value); 693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(1, effect); 694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->TrimInputCount(2); 695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, common()->FinishRegion()); 696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Changed(node); 697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSComparison(Node* node) { 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::String())) { 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If both inputs are definitely strings, perform a string comparison. 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* stringOp; 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThan: 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThan(); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThan: 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThan(); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch r.SwapInputs(); // a > b => b < a 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThanOrEqual: 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThanOrEqual(); 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThanOrEqual: 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThanOrEqual(); 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch r.SwapInputs(); // a >= b => b <= a 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch r.ChangeToPureOperator(stringOp); 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 72513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* less_than; 728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* less_than_or_equal; 729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::Signed32()) || 730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::Unsigned32())) { 731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than = simplified()->NumberLessThan(); 732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than_or_equal = simplified()->NumberLessThanOrEqual(); 733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.GetCompareNumberOperationHint(&hint)) { 734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than = simplified()->SpeculativeNumberLessThan(hint); 735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint); 736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.OneInputCannotBe(Type::StringOrReceiver()) && 737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (r.BothInputsAre(Type::PlainPrimitive()) || 738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled))) { 739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than = simplified()->NumberLessThan(); 741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than_or_equal = simplified()->NumberLessThanOrEqual(); 742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* comparison; 746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node->opcode()) { 747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSLessThan: 748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than; 749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSGreaterThan: 751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than; 752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.SwapInputs(); // a > b => b < a 753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSLessThanOrEqual: 755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than_or_equal; 756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSGreaterThanOrEqual: 758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than_or_equal; 759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.SwapInputs(); // a >= b => b <= a 760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (comparison->EffectInputCount() > 0) { 765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator(comparison, Type::Boolean()); 766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(comparison); 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 771bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochReduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) { 772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HeapObjectBinopMatcher m(node); 773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (m.left().IsJSTypeOf() && m.right().HasValue() && 774bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch m.right().Value()->IsString()) { 775bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* replacement; 776bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* input = m.left().InputAt(0); 777bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<String> value = Handle<String>::cast(m.right().Value()); 778bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (String::Equals(value, factory()->boolean_string())) { 779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch replacement = 780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Select(MachineRepresentation::kTagged), 781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), 782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input, jsgraph()->TrueConstant()), 783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->TrueConstant(), 784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), 785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input, jsgraph()->FalseConstant())); 786bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (String::Equals(value, factory()->function_string())) { 787bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch replacement = graph()->NewNode(simplified()->ObjectIsCallable(), input); 788bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (String::Equals(value, factory()->number_string())) { 789bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch replacement = graph()->NewNode(simplified()->ObjectIsNumber(), input); 790bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (String::Equals(value, factory()->string_string())) { 791bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch replacement = graph()->NewNode(simplified()->ObjectIsString(), input); 792bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (String::Equals(value, factory()->undefined_string())) { 793bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch replacement = graph()->NewNode( 794bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch common()->Select(MachineRepresentation::kTagged), 795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), input, 796bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch jsgraph()->NullConstant()), 797bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch jsgraph()->FalseConstant(), 798bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch graph()->NewNode(simplified()->ObjectIsUndetectable(), input)); 799bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 800bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return NoChange(); 801bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 802bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (invert) { 803bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); 804bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, replacement); 806bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Replace(replacement); 807bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 808bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return NoChange(); 809bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { 812bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (reduction.Changed()) return reduction; 814bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::String())) { 818bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (r.BothInputsAre(Type::Boolean())) { 821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::Receiver())) { 824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 8263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (r.OneInputIs(Type::Undetectable())) { 8273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelaxEffectsAndControls(node); 8283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1); 8293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch node->TrimInputCount(1); 8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable()); 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (invert) { 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert an boolean not to invert the value. 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = graph()->NewNode(simplified()->BooleanNot(), node); 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceUses(value); 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note: ReplaceUses() smashes all uses, so smash it back here. 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value->ReplaceInput(0, node); 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(value); 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::Signed32()) || 844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::Unsigned32())) { 845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.GetCompareNumberOperationHint(&hint)) { 847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator( 848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.BothInputsAre(Type::Number())) { 850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.left() == r.right()) { 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // x === x is always true if x != NaN 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!r.left_type()->Maybe(Type::NaN())) { 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* replacement = jsgraph()->BooleanConstant(!invert); 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, replacement); 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(replacement); 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 86513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) { 86613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // For values with canonical representation (i.e. neither String, nor 86713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Simd128Value nor Number) an empty type intersection means the values 86813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // cannot be strictly equal. 869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!r.left_type()->Maybe(r.right_type())) { 870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* replacement = jsgraph()->BooleanConstant(invert); 871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, replacement); 872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(replacement); 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 876bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (reduction.Changed()) return reduction; 878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (r.OneInputIs(the_hole_type_)) { 880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.OneInputIs(Type::Undefined())) { 883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.OneInputIs(Type::Null())) { 886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.OneInputIs(Type::Boolean())) { 889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.OneInputIs(Type::Object())) { 892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.OneInputIs(Type::Receiver())) { 895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (r.BothInputsAre(Type::Unique())) { 898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::String())) { 901bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::Signed32()) || 906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::Unsigned32())) { 907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.GetCompareNumberOperationHint(&hint)) { 909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator( 910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.BothInputsAre(Type::Number())) { 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToBoolean(Node* node) { 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const input = node->InputAt(0); 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* const input_type = NodeProperties::GetType(input); 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (input_type->Is(Type::Boolean())) { 921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSToBoolean(x:boolean) => x 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(input); 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (input_type->Is(Type::OrderedNumber())) { 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelaxEffectsAndControls(node); 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->ZeroConstant())); 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(1); 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, simplified()->BooleanNot()); 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (input_type->Is(Type::Number())) { 932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // JSToBoolean(x:number) => NumberToBoolean(x) 933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RelaxEffectsAndControls(node); 934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->TrimInputCount(1); 935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, simplified()->NumberToBoolean()); 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 9413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochReduction JSTypedLowering::ReduceJSToInteger(Node* node) { 9423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* const input = NodeProperties::GetValueInput(node, 0); 9433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Type* const input_type = NodeProperties::GetType(input); 9443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Is(type_cache_.kIntegerOrMinusZero)) { 9453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // JSToInteger(x:integer) => x 9463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReplaceWithValue(node, input); 9473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Replace(input); 9483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return NoChange(); 9503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 9513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochReduction JSTypedLowering::ReduceJSToLength(Node* node) { 9533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* input = NodeProperties::GetValueInput(node, 0); 9543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Type* input_type = NodeProperties::GetType(input); 9553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Is(type_cache_.kIntegerOrMinusZero)) { 9563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Max() <= 0.0) { 9573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch input = jsgraph()->ZeroConstant(); 9583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (input_type->Min() >= kMaxSafeInteger) { 9593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch input = jsgraph()->Constant(kMaxSafeInteger); 9603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 9613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Min() <= 0.0) { 962f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch input = graph()->NewNode(simplified()->NumberMax(), 963f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->ZeroConstant(), input); 9643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Max() > kMaxSafeInteger) { 966f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch input = graph()->NewNode(simplified()->NumberMin(), 967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(kMaxSafeInteger), input); 9683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReplaceWithValue(node, input); 9713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Replace(input); 9723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return NoChange(); 9743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { 977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Try constant-folding of JSToNumber with constant inputs. 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* input_type = NodeProperties::GetType(input); 979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (input_type->IsConstant()) { 980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> input_value = input_type->AsConstant()->Value(); 981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (input_value->IsString()) { 982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Replace(jsgraph()->Constant( 983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch String::ToNumber(Handle<String>::cast(input_value)))); 984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (input_value->IsOddball()) { 985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Replace(jsgraph()->Constant( 986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Oddball::ToNumber(Handle<Oddball>::cast(input_value)))); 987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Number())) { 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSToNumber(x:number) => x 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Changed(input); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Undefined())) { 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSToNumber(undefined) => #NaN 995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->NaNConstant()); 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Null())) { 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSToNumber(null) => #0 999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->ZeroConstant()); 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToNumber(Node* node) { 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to reduce the input first. 1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const input = node->InputAt(0); 1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction reduction = ReduceJSToNumberInput(input); 1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reduction.Changed()) { 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, reduction.replacement()); 1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reduction; 1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* const input_type = NodeProperties::GetType(input); 1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (input_type->Is(Type::PlainPrimitive())) { 101413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelaxEffectsAndControls(node); 101513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch node->TrimInputCount(1); 101613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::ChangeOp(node, simplified()->PlainPrimitiveToNumber()); 101713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(node); 1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NoChange(); 1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSToStringInput(Node* input) { 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input->opcode() == IrOpcode::kJSToString) { 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Recursively try to reduce the input first. 1025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction result = ReduceJSToString(input); 1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result.Changed()) return result; 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Changed(input); // JSToString(JSToString(x)) => JSToString(x) 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* input_type = NodeProperties::GetType(input); 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::String())) { 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Changed(input); // JSToString(x:string) => x 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input_type->Is(Type::Boolean())) { 1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(graph()->NewNode( 1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch common()->Select(MachineRepresentation::kTagged), input, 1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(factory()->true_string()), 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(factory()->false_string()))); 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Undefined())) { 1040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->HeapConstant(factory()->undefined_string())); 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Null())) { 1043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->HeapConstant(factory()->null_string())); 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(turbofan): js-typed-lowering of ToString(x:number) 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1049958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToString(Node* node) { 1050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to reduce the input first. 1051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const input = node->InputAt(0); 1052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction reduction = ReduceJSToStringInput(input); 1053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reduction.Changed()) { 1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, reduction.replacement()); 1055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reduction; 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSToObject(Node* node) { 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSToObject, node->opcode()); 1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1065f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1068f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Is(Type::Receiver())) { 1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, receiver, effect, control); 1070f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Replace(receiver); 1071f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1073f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks. 1074f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Maybe(Type::NullOrUndefined()) && 1075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::IsExceptionalCall(node)) { 1076f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ToObject throws for null or undefined inputs. 1077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 1078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check whether {receiver} is a spec object. 1081f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver); 1082f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch = 1083f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1085f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1086f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* etrue = effect; 1087f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rtrue = receiver; 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1089f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1090f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* efalse = effect; 1091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rfalse; 1092f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert {receiver} using the ToObjectStub. 1094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::ToObject(isolate()); 1095f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 1097f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState, node->op()->properties()); 1098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rfalse = efalse = graph()->NewNode( 1099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 1100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, context, frame_state, efalse, if_false); 1101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_false = graph()->NewNode(common()->IfSuccess(), rfalse); 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Morph the {node} into an appropriate Phi. 1108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, node, effect, control); 1109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, rtrue); 1110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(1, rfalse); 1111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(2, control); 1112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->TrimInputCount(3); 1113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, 1114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Phi(MachineRepresentation::kTagged, 2)); 1115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 1116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = NamedAccessOf(node->op()).name(); 1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimize "length" property of strings. 1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (name.is_identical_to(factory()->length_string()) && 1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_type->Is(Type::String())) { 1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = effect = graph()->NewNode( 1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, 1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect, control); 1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, value, effect); 1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(value); 1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = NodeProperties::GetValueInput(node, 1); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = NodeProperties::GetValueInput(node, 0); 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* key_type = NodeProperties::GetType(key); 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObjectMatcher mbase(base); 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) { 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSTypedArray> const array = 1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSTypedArray>::cast(mbase.Value()); 1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!array->GetBuffer()->was_neutered()) { 1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->GetBuffer()->set_is_neuterable(false); 1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferAccess const access(array->type()); 1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const k = 1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementSizeLog2Of(access.machine_type().representation()); 1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double const byte_length = array->byte_length()->Number(); 1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LT(k, arraysize(shifted_int32_ranges_)); 1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { 1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSLoadProperty(typed-array, int32) 1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase> elements = 1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase>::cast(handle(array->elements())); 1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); 1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* length = jsgraph()->Constant(byte_length); 1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if we can avoid the bounds check. 1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) { 1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* load = graph()->NewNode( 1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadElement( 1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForTypedArrayElement(array->type(), true)), 1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer, key, effect, control); 1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, load, load); 1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(load); 1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute byte offset. 1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* offset = 1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (k == 0) ? key : graph()->NewNode( 1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->NumberShiftLeft(), key, 1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->Constant(static_cast<double>(k))); 1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer, 1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset, length, effect, control); 1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, load, load); 1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(load); 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = NodeProperties::GetValueInput(node, 1); 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = NodeProperties::GetValueInput(node, 0); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = NodeProperties::GetValueInput(node, 2); 1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* key_type = NodeProperties::GetType(key); 1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* value_type = NodeProperties::GetType(value); 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObjectMatcher mbase(base); 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) { 1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSTypedArray> const array = 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSTypedArray>::cast(mbase.Value()); 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!array->GetBuffer()->was_neutered()) { 1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->GetBuffer()->set_is_neuterable(false); 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferAccess const access(array->type()); 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const k = 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementSizeLog2Of(access.machine_type().representation()); 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double const byte_length = array->byte_length()->Number(); 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LT(k, arraysize(shifted_int32_ranges_)); 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access.external_array_type() != kExternalUint8ClampedArray && 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSLoadProperty(typed-array, int32) 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase> elements = 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase>::cast(handle(array->elements())); 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); 1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* length = jsgraph()->Constant(byte_length); 1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convert to a number first. 121213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!value_type->Is(Type::Number())) { 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Reduction number_reduction = ReduceJSToNumberInput(value); 1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (number_reduction.Changed()) { 1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = number_reduction.replacement(); 1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* frame_state_for_to_number = 121813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::FindFrameStateBefore(node); 1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = effect = 1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ToNumber(), value, context, 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_state_for_to_number, effect, control); 1222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = graph()->NewNode(common()->IfSuccess(), value); 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if we can avoid the bounds check. 1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) { 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelaxControls(node); 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, buffer); 1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(key, node->InputAt(1)); 1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, value); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(3, effect); 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(4, control); 1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(5); 1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, 1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->StoreElement( 1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForTypedArrayElement(array->type(), true))); 1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute byte offset. 1241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* offset = 1242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (k == 0) ? key : graph()->NewNode( 1243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->NumberShiftLeft(), key, 1244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->Constant(static_cast<double>(k))); 1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Turn into a StoreBuffer operation. 1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelaxControls(node); 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->ReplaceInput(0, buffer); 1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(1, offset); 1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, length); 1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(3, value); 1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(4, effect); 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(5, control); 1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(6); 1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access)); 1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Changed(node); 1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochReduction JSTypedLowering::ReduceJSOrdinaryHasInstance(Node* node) { 1263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode()); 1264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* constructor = NodeProperties::GetValueInput(node, 0); 1265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type* constructor_type = NodeProperties::GetType(constructor); 1266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* object = NodeProperties::GetValueInput(node, 1); 1267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 1269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {constructor} is a (known) JSFunction. 1273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!constructor_type->IsConstant() || 1274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !constructor_type->AsConstant()->Value()->IsJSFunction()) { 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 1278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<JSFunction>::cast(constructor_type->AsConstant()->Value()); 1279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {function} already has an initial map (i.e. the 1281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // {function} has been used as a constructor at least once). 1282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!function->has_initial_map()) return NoChange(); 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {function}s "prototype" is a JSReceiver. 1285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!function->prototype()->IsJSReceiver()) return NoChange(); 1286bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Install a code dependency on the {function}s initial map. 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> initial_map(function->initial_map(), isolate()); 1289bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch dependencies()->AssumeInitialMapCantChange(initial_map); 1290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* prototype = 1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->Constant(handle(initial_map->prototype(), isolate())); 1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), object); 1295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch0 = 1296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control); 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue0 = effect; 1300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue0 = jsgraph()->FalseConstant(); 1301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch0); 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Loop through the {object}s prototype chain looking for the {prototype}. 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* loop = control = graph()->NewNode(common()->Loop(2), control, control); 1306f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* eloop = effect = 1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->EffectPhi(2), effect, effect, loop); 1308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vloop = object = graph()->NewNode( 1309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->Phi(MachineRepresentation::kTagged, 2), object, object, loop); 1310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(jarin): This is a very ugly hack to work-around the super-smart 1311f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // implicit typing of the Phi, which goes completely nuts if the {object} 1312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // is for example a HeapConstant. 1313f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::SetType(vloop, Type::NonInternal()); 1314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1315f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Load the {object} map and instance type. 1316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* object_map = effect = 1317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, 1318f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* object_instance_type = effect = graph()->NewNode( 1320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForMapInstanceType()), object_map, 1321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {object} is a special receiver, because for special 1324f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // receivers, i.e. proxies or API objects that need access checks, 1325f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // we have to use the %HasInPrototypeChain runtime function instead. 1326f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check1 = graph()->NewNode( 1327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->NumberLessThanOrEqual(), object_instance_type, 1328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(LAST_SPECIAL_RECEIVER_TYPE)); 1329f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch1 = 1330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch1); 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue1 = effect; 1336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue1; 1337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {object} is not a receiver at all. 1339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check10 = 1340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->NumberLessThan(), object_instance_type, 1341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(FIRST_JS_RECEIVER_TYPE)); 1342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch10 = 1343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check10, if_true1); 1344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // A primitive value cannot match the {prototype} we're looking for. 1346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_true1 = graph()->NewNode(common()->IfTrue(), branch10); 1347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vtrue1 = jsgraph()->FalseConstant(); 1348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch10); 1350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* efalse1 = etrue1; 1351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vfalse1; 1352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 1353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Slow path, need to call the %HasInPrototypeChain runtime function. 1354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vfalse1 = efalse1 = graph()->NewNode( 1355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch javascript()->CallRuntime(Runtime::kHasInPrototypeChain), object, 1356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch prototype, context, frame_state, efalse1, if_false1); 1357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_false1 = graph()->NewNode(common()->IfSuccess(), vfalse1); 1358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Replace any potential IfException on {node} to catch exceptions 1360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // from this %HasInPrototypeChain runtime call instead. 1361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (Edge edge : node->use_edges()) { 1362f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (edge.from()->opcode() == IrOpcode::kIfException) { 1363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch edge.UpdateTo(vfalse1); 1364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Revisit(edge.from()); 1365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Load the {object} prototype. 1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* object_prototype = effect = graph()->NewNode( 1371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForMapPrototype()), object_map, 1372f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1374f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we reached the end of {object}s prototype chain. 1375f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(), 1376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object_prototype, jsgraph()->NullConstant()); 1377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch2 = graph()->NewNode(common()->Branch(), check2, control); 1378f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 1380f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue2 = effect; 1381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue2 = jsgraph()->FalseConstant(); 1382f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch2); 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we reached the {prototype}. 1386f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check3 = graph()->NewNode(simplified()->ReferenceEqual(), 1387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object_prototype, prototype); 1388f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch3 = graph()->NewNode(common()->Branch(), check3, control); 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3); 1391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue3 = effect; 1392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue3 = jsgraph()->TrueConstant(); 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch3); 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Close the loop. 1397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vloop->ReplaceInput(1, object_prototype); 1398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch eloop->ReplaceInput(1, effect); 1399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch loop->ReplaceInput(1, control); 1400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1401f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->Merge(5), if_true0, if_true1, if_true2, 1402f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_true3, if_false1); 1403f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode(common()->EffectPhi(5), etrue0, etrue1, etrue2, 1404f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch etrue3, efalse1, control); 1405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Morph the {node} into an appropriate Phi. 1407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ReplaceWithValue(node, node, effect, control); 1408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(0, vtrue0); 1409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(1, vtrue1); 1410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(2, vtrue2); 1411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(3, vtrue3); 1412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(4, vfalse1); 1413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(5, control); 1414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->TrimInputCount(6); 1415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, 1416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->Phi(MachineRepresentation::kTagged, 5)); 1417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Changed(node); 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSLoadContext(Node* node) { 1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); 1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ContextAccess const& access = ContextAccessOf(node->op()); 1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = graph()->start(); 1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < access.depth(); ++i) { 1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* previous = effect = graph()->NewNode( 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField( 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), 1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::GetValueInput(node, 0), effect, control); 1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, previous); 1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->ReplaceInput(1, effect); 1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->ReplaceInput(2, control); 1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, 1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField(AccessBuilder::ForContextSlot(access.index()))); 1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Changed(node); 1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSStoreContext(Node* node) { 1441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); 1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ContextAccess const& access = ContextAccessOf(node->op()); 1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = graph()->start(); 1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < access.depth(); ++i) { 1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* previous = effect = graph()->NewNode( 1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField( 1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), 1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::GetValueInput(node, 0), effect, control); 1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, previous); 1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->RemoveInput(2); 1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, effect); 1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->StoreField(AccessBuilder::ForContextSlot(access.index()))); 1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* context_type = NodeProperties::GetType(context); 1467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1470f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1471f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if {receiver} is known to be a receiver. 1472f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Is(Type::Receiver())) { 1473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, receiver, effect, control); 1474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Replace(receiver); 1475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If the {receiver} is known to be null or undefined, we can just replace it 1478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // with the global proxy unconditionally. 1479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Is(Type::NullOrUndefined()) || 1480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch mode == ConvertReceiverMode::kNullOrUndefined) { 1481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (context_type->IsConstant()) { 1482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> global_proxy( 1483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Context>::cast(context_type->AsConstant()->Value()) 1484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ->global_proxy(), 1485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate()); 1486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver = jsgraph()->Constant(global_proxy); 1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* native_context = effect = graph()->NewNode( 1489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 1490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context, context, effect); 1491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver = effect = graph()->NewNode( 1492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true), 1493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch native_context, native_context, effect); 1494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, receiver, effect, control); 1496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Replace(receiver); 1497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If {receiver} cannot be null or undefined we can skip a few checks. 1500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!receiver_type->Maybe(Type::NullOrUndefined()) || 1501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch mode == ConvertReceiverMode::kNotNullOrUndefined) { 1502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver); 1503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch = 1504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* etrue = effect; 1508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rtrue = receiver; 1509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* efalse = effect; 1512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rfalse; 1513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert {receiver} using the ToObjectStub. 1515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::ToObject(isolate()); 1516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 1518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState, node->op()->properties()); 1519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rfalse = efalse = graph()->NewNode( 1520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 1521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, context, frame_state, efalse); 1522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Morph the {node} into an appropriate Phi. 1528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, node, effect, control); 1529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, rtrue); 1530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(1, rfalse); 1531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(2, control); 1532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->TrimInputCount(3); 1533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, 1534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Phi(MachineRepresentation::kTagged, 2)); 1535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 1536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if {receiver} is already a JSReceiver. 1539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check0 = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver); 1540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch0 = 1541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check {receiver} for undefined. 1546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check1 = graph()->NewNode(simplified()->ReferenceEqual(), receiver, 1547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->UndefinedConstant()); 1548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch1 = 1549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_false0); 1550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 1552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check {receiver} for null. 1554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(), receiver, 1555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->NullConstant()); 1556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch2 = 1557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check2, if_false1); 1558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 1559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); 1560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We just use {receiver} directly. 1562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_noop = if_true0; 1563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* enoop = effect; 1564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rnoop = receiver; 1565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert {receiver} using ToObject. 1567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_convert = if_false2; 1568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* econvert = effect; 1569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rconvert; 1570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert {receiver} using the ToObjectStub. 1572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::ToObject(isolate()); 1573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 1575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState, node->op()->properties()); 1576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rconvert = econvert = graph()->NewNode( 1577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 1578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, context, frame_state, econvert); 1579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Replace {receiver} with global proxy of {context}. 1582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_global = graph()->NewNode(common()->Merge(2), if_true1, if_true2); 1583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* eglobal = effect; 1584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rglobal; 1585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (context_type->IsConstant()) { 1587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> global_proxy( 1588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Context>::cast(context_type->AsConstant()->Value()) 1589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ->global_proxy(), 1590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate()); 1591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rglobal = jsgraph()->Constant(global_proxy); 1592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* native_context = eglobal = graph()->NewNode( 1594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 1595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context, context, eglobal); 1596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rglobal = eglobal = graph()->NewNode( 1597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true), 1598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch native_context, native_context, eglobal); 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = 1603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Merge(3), if_noop, if_convert, if_global); 1604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect = graph()->NewNode(common()->EffectPhi(3), enoop, econvert, eglobal, 1605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control); 1606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Morph the {node} into an appropriate Phi. 1607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, node, effect, control); 1608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, rnoop); 1609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(1, rconvert); 1610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(2, rglobal); 1611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(3, control); 1612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->TrimInputCount(4); 1613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, 1614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Phi(MachineRepresentation::kTagged, 3)); 1615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 1619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node, 1621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int builtin_index, int arity, CallDescriptor::Flags flags) { 1622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Patch {node} to a direct CEntryStub call. 1623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // 1624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ----------- A r g u m e n t s ----------- 1625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 0: CEntryStub 1626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // --- Stack args --- 1627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 1: receiver 1628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- [2, 2 + n[: the n actual arguments passed to the builtin 1629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n: argc, including the receiver and implicit args (Smi) 1630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 1: target 1631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 2: new_target 1632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // --- Register args --- 1633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 3: the C entry point 1634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 4: argc (Int32) 1635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ----------------------------------- 1636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // The logic contained here is mirrored in Builtins::Generate_Adaptor. 1638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Keep these in sync. 1639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool is_construct = (node->opcode() == IrOpcode::kJSCallConstruct); 1641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(Builtins::HasCppImplementation(builtin_index)); 1643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 1645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* new_target = is_construct 1646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? NodeProperties::GetValueInput(node, arity + 1) 1647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : jsgraph->UndefinedConstant(); 1648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // API and CPP builtins are implemented in C++, and we can inline both. 1650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // CPP builtins create a builtin exit frame, API builtins don't. 1651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index); 1652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack, 1654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch has_builtin_exit_frame); 1655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, stub); 1656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Zone* zone = jsgraph->zone(); 1658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (is_construct) { 1659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Unify representations between construct and call nodes. 1660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Remove new target and add receiver as a stack parameter. 1661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* receiver = jsgraph->UndefinedConstant(); 1662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->RemoveInput(arity + 1); 1663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(zone, 1, receiver); 1664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver; 1667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* argc_node = jsgraph->Int32Constant(argc); 1668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch static const int kStubAndReceiver = 2; 1670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int cursor = arity + kStubAndReceiver; 1671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, argc_node); 1672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, target); 1673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, new_target); 1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Address entry = Builtins::CppEntryOf(builtin_index); 1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalReference entry_ref(ExternalReference(entry, isolate)); 1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* entry_node = jsgraph->ExternalConstant(entry_ref); 1678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, entry_node); 1680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, argc_node); 1681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static const int kReturnCount = 1; 1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const char* debug_name = Builtins::name(builtin_index); 1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Operator::Properties properties = node->op()->properties(); 1685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor( 1686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch zone, kReturnCount, argc, debug_name, properties, flags); 1687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc)); 1689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool NeedsArgumentAdaptorFrame(Handle<SharedFunctionInfo> shared, int arity) { 1692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch static const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; 1693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const int num_decl_parms = shared->internal_formal_parameter_count(); 1694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return (num_decl_parms != arity && num_decl_parms != sentinel); 1695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSCallConstruct(Node* node) { 1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); 1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallConstructParameters const& p = CallConstructParametersOf(node->op()); 1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LE(2u, p.arity()); 1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const arity = static_cast<int>(p.arity() - 2); 1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* target_type = NodeProperties::GetType(target); 1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* new_target = NodeProperties::GetValueInput(node, arity + 1); 1707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* control = NodeProperties::GetControlInput(node); 1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a known JSFunction. 1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_type->IsConstant() && 1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_type->AsConstant()->Value()->IsJSFunction()) { 1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction>::cast(target_type->AsConstant()->Value()); 1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 1716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int builtin_index = shared->construct_stub()->builtin_index(); 1717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool is_builtin = (builtin_index != -1); 1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 1720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (is_builtin && Builtins::HasCppImplementation(builtin_index) && 1722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !NeedsArgumentAdaptorFrame(shared, arity)) { 1723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Patch {node} to a direct CEntryStub call. 1724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Load the context from the {target}. 1726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* context = effect = graph()->NewNode( 1727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), 1728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch target, effect, control); 1729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ReplaceContextInput(node, context); 1730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Update the effect dependency for the {node}. 1732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ReplaceEffectInput(node, effect); 1733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); 1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Patch {node} to an indirect call via the {function}s construct stub. 1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable(handle(shared->construct_stub(), isolate()), 1738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ConstructStubDescriptor(isolate())); 1739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->RemoveInput(arity + 1); 1740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 0, 1741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->HeapConstant(callable.code())); 1742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 2, new_target); 1743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); 1744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 1745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant()); 1746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp( 1747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 1748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 1749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1 + arity, flags))); 1750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a JSFunction. 1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_type->Is(Type::Function())) { 1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch {node} to an indirect call via the ConstructFunction builtin. 1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::ConstructFunction(isolate()); 1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->RemoveInput(arity + 1); 1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 2, new_target); 1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); 1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 1 + arity, 1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::kNeedsFrameState))); 1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSCallFunction(Node* node) { 1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const arity = static_cast<int>(p.arity() - 2); 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertReceiverMode convert_mode = p.convert_mode(); 1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* target_type = NodeProperties::GetType(target); 1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 1); 1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 178613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* frame_state = NodeProperties::FindFrameStateBefore(node); 1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to infer receiver {convert_mode} from {receiver} type. 1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (receiver_type->Is(Type::NullOrUndefined())) { 1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch convert_mode = ConvertReceiverMode::kNullOrUndefined; 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (!receiver_type->Maybe(Type::NullOrUndefined())) { 1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a known JSFunction. 1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_type->IsConstant() && 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_type->AsConstant()->Value()->IsJSFunction()) { 1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction>::cast(target_type->AsConstant()->Value()); 1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 1801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int builtin_index = shared->code()->builtin_index(); 1802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool is_builtin = (builtin_index != -1); 1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Class constructors are callable, but [[Call]] will raise an exception. 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). 1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsClassConstructor(shared->kind())) return NoChange(); 1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the context from the {target}. 1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = effect = graph()->NewNode( 1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target, 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect, control); 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceContextInput(node, context); 1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if we need to convert the {receiver}. 1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_sloppy(shared->language_mode()) && !shared->native() && 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !receiver_type->Is(Type::Receiver())) { 1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = effect = 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ConvertReceiver(convert_mode), 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver, context, frame_state, effect, control); 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceValueInput(node, receiver, 1); 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Update the effect dependency for the {node}. 1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceEffectInput(node, effect); 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute flags for the call. 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p.tail_call_mode() == TailCallMode::kAllow) { 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= CallDescriptor::kSupportsTailCalls; 1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* new_target = jsgraph()->UndefinedConstant(); 1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* argument_count = jsgraph()->Int32Constant(arity); 1834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (NeedsArgumentAdaptorFrame(shared, arity)) { 1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline. 1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::ArgumentAdaptor(isolate()); 1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 2, new_target); 1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 3, argument_count); 1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput( 1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->zone(), 4, 1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->Int32Constant(shared->internal_formal_parameter_count())); 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1 + arity, flags))); 1848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (is_builtin && Builtins::HasCppImplementation(builtin_index)) { 1849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Patch {node} to a direct CEntryStub call. 1850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); 1851f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 1852f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Patch {node} to a direct call. 1853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(graph()->zone(), arity + 2, new_target); 1854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(graph()->zone(), arity + 3, argument_count); 1855f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, 1856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->Call(Linkage::GetJSCallDescriptor( 1857f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->zone(), false, 1 + arity, flags))); 1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a JSFunction. 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_type->Is(Type::Function())) { 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute flags for the call. 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p.tail_call_mode() == TailCallMode::kAllow) { 1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= CallDescriptor::kSupportsTailCalls; 1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch {node} to an indirect call via the CallFunction builtin. 1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::CallFunction(isolate(), convert_mode); 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 2, jsgraph()->Int32Constant(arity)); 1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 1 + arity, 1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags))); 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Maybe we did at least learn something about the {receiver}. 1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p.convert_mode() != convert_mode) { 1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node, javascript()->CallFunction(p.arity(), p.frequency(), p.feedback(), 1886f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch convert_mode, p.tail_call_mode())); 1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSForInNext(Node* node) { 1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode()); 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* cache_array = NodeProperties::GetValueInput(node, 1); 1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* cache_type = NodeProperties::GetValueInput(node, 2); 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* index = NodeProperties::GetValueInput(node, 3); 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the next {key} from the {cache_array}. 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* key = effect = graph()->NewNode( 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cache_array, index, effect, control); 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the map of the {receiver}. 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver_map = effect = 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver, effect, control); 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if the expected map still matches that of the {receiver}. 1916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map, 1917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cache_type); 1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* branch0 = 1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* etrue0; 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* vtrue0; 1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't need filtering since expected map still matches that of the 1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {receiver}. 1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch etrue0 = effect; 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vtrue0 = key; 1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* efalse0; 1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* vfalse0; 1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Filter the {key} to check if it's still a valid property of the 1936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // {receiver} (does the ToName conversion implicitly). 1937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable const callable = CodeFactory::ForInFilter(isolate()); 1938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 1940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 1941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vfalse0 = efalse0 = graph()->NewNode( 1942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), key, 1943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, context, frame_state, effect, if_false0); 1944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0); 1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, node, effect, control); 1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, vtrue0); 1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(1, vfalse0); 1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, control); 1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(3); 1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, 1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch common()->Phi(MachineRepresentation::kTagged, 2)); 1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 195913e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) { 196013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode()); 196113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* generator = NodeProperties::GetValueInput(node, 0); 196213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* continuation = NodeProperties::GetValueInput(node, 1); 196313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* offset = NodeProperties::GetValueInput(node, 2); 196413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context = NodeProperties::GetContextInput(node); 196513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 196613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 196713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int register_count = OpParameter<int>(node); 196813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 196913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectOperandStack(); 197013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext(); 197113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess continuation_field = 197213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessBuilder::ForJSGeneratorObjectContinuation(); 197313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess input_or_debug_pos_field = 197413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(); 197513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 197613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field), 197713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, effect, control); 197813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 197913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (int i = 0; i < register_count; ++i) { 198013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* value = NodeProperties::GetValueInput(node, 3 + i); 198113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode( 198213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array, 198313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value, effect, control); 198413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 198513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 198613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(context_field), generator, 198713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch context, effect, control); 198813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(continuation_field), 198913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, continuation, effect, control); 199013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field), 199113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, offset, effect, control); 199213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 199313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ReplaceWithValue(node, effect, effect, control); 199413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(effect); 199513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 199613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 199713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorRestoreContinuation(Node* node) { 199813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kJSGeneratorRestoreContinuation, node->opcode()); 199913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* generator = NodeProperties::GetValueInput(node, 0); 200013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 200113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 200213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 200313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess continuation_field = 200413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessBuilder::ForJSGeneratorObjectContinuation(); 200513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 200613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* continuation = effect = graph()->NewNode( 200713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch simplified()->LoadField(continuation_field), generator, effect, control); 200813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* executing = jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting); 200913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(continuation_field), 201013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, executing, effect, control); 201113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 201213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ReplaceWithValue(node, continuation, effect, control); 201313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(continuation); 201413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 201513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 201613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorRestoreRegister(Node* node) { 201713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, node->opcode()); 201813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* generator = NodeProperties::GetValueInput(node, 0); 201913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 202013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 202113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int index = OpParameter<int>(node); 202213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 202313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectOperandStack(); 202413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess element_field = AccessBuilder::ForFixedArraySlot(index); 202513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 202613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field), 202713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, effect, control); 202813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* element = effect = graph()->NewNode( 202913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch simplified()->LoadField(element_field), array, effect, control); 203013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* stale = jsgraph()->StaleRegisterConstant(); 203113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(element_field), array, 203213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stale, effect, control); 203313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 203413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ReplaceWithValue(node, element, effect, control); 203513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(element); 203613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::Reduce(Node* node) { 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSEqual: 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSEqual(node, false); 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSNotEqual: 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSEqual(node, true); 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSStrictEqual: 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSStrictEqual(node, false); 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSStrictNotEqual: 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSStrictEqual(node, true); 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThan: // fall through 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThan: // fall through 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThanOrEqual: // fall through 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThanOrEqual: 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSComparison(node); 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSBitwiseOr: 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSBitwiseXor: 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSBitwiseAnd: 2056f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceInt32Binop(node); 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSShiftLeft: 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSShiftRight: 2059f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceUI32Shift(node, kSigned); 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSShiftRightLogical: 2061f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceUI32Shift(node, kUnsigned); 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSAdd: 2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSAdd(node); 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSSubtract: 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSMultiply: 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSDivide: 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSModulus: 2068f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceNumberBinop(node); 2069f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kJSOrdinaryHasInstance: 2070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ReduceJSOrdinaryHasInstance(node); 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSToBoolean: 2072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSToBoolean(node); 20733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case IrOpcode::kJSToInteger: 20743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ReduceJSToInteger(node); 20753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case IrOpcode::kJSToLength: 20763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ReduceJSToLength(node); 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSToNumber: 2078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSToNumber(node); 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSToString: 2080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSToString(node); 2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSToObject: 2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSToObject(node); 2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSLoadNamed: 2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSLoadNamed(node); 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLoadProperty: 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSLoadProperty(node); 2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSStoreProperty: 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSStoreProperty(node); 2089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kJSLoadContext: 2090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSLoadContext(node); 2091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kJSStoreContext: 2092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSStoreContext(node); 2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSConvertReceiver: 2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSConvertReceiver(node); 2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSCallConstruct: 2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSCallConstruct(node); 2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSCallFunction: 2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSCallFunction(node); 2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSForInNext: 2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSForInNext(node); 210113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kJSGeneratorStore: 210213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ReduceJSGeneratorStore(node); 210313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kJSGeneratorRestoreContinuation: 210413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ReduceJSGeneratorRestoreContinuation(node); 210513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kJSGeneratorRestoreRegister: 210613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ReduceJSGeneratorRestoreRegister(node); 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierFactory* JSTypedLowering::factory() const { return jsgraph()->factory(); } 2115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierGraph* JSTypedLowering::graph() const { return jsgraph()->graph(); } 2118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIsolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); } 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierJSOperatorBuilder* JSTypedLowering::javascript() const { 2124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return jsgraph()->javascript(); 2125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCommonOperatorBuilder* JSTypedLowering::common() const { 2129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return jsgraph()->common(); 2130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSimplifiedOperatorBuilder* JSTypedLowering::simplified() const { 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return jsgraph()->simplified(); 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCompilationDependencies* JSTypedLowering::dependencies() const { 2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return dependencies_; 2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 2144