diff options
Diffstat (limited to 'deps/v8/src/compiler/js-typed-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/js-typed-lowering.cc | 119 |
1 files changed, 96 insertions, 23 deletions
diff --git a/deps/v8/src/compiler/js-typed-lowering.cc b/deps/v8/src/compiler/js-typed-lowering.cc index fa6c559a4d..a26ee1a517 100644 --- a/deps/v8/src/compiler/js-typed-lowering.cc +++ b/deps/v8/src/compiler/js-typed-lowering.cc @@ -58,6 +58,7 @@ class JSBinopReduction final { case CompareOperationHint::kString: case CompareOperationHint::kSymbol: case CompareOperationHint::kBigInt: + case CompareOperationHint::kBigInt64: case CompareOperationHint::kReceiver: case CompareOperationHint::kReceiverOrNullOrUndefined: case CompareOperationHint::kInternalizedString: @@ -66,6 +67,31 @@ class JSBinopReduction final { return false; } + bool GetCompareBigIntOperationHint(BigIntOperationHint* hint) { + DCHECK_EQ(1, node_->op()->EffectOutputCount()); + switch (GetCompareOperationHint(node_)) { + case CompareOperationHint::kSignedSmall: + case CompareOperationHint::kNumber: + case CompareOperationHint::kNumberOrBoolean: + case CompareOperationHint::kNumberOrOddball: + case CompareOperationHint::kAny: + case CompareOperationHint::kNone: + case CompareOperationHint::kString: + case CompareOperationHint::kSymbol: + case CompareOperationHint::kReceiver: + case CompareOperationHint::kReceiverOrNullOrUndefined: + case CompareOperationHint::kInternalizedString: + return false; + case CompareOperationHint::kBigInt: + *hint = BigIntOperationHint::kBigInt; + return true; + case CompareOperationHint::kBigInt64: + *hint = BigIntOperationHint::kBigInt64; + return true; + } + UNREACHABLE(); + } + bool IsInternalizedStringCompareOperation() { DCHECK_EQ(1, node_->op()->EffectOutputCount()); return (GetCompareOperationHint(node_) == @@ -451,7 +477,7 @@ JSTypedLowering::JSTypedLowering(Editor* editor, JSGraph* jsgraph, jsgraph_(jsgraph), broker_(broker), empty_string_type_( - Type::Constant(broker, factory()->empty_string(), graph()->zone())), + Type::Constant(broker, broker->empty_string(), graph()->zone())), pointer_comparable_type_( Type::Union(Type::Oddball(), Type::Union(Type::SymbolOrReceiver(), empty_string_type_, @@ -593,9 +619,9 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) { PropertyCellRef string_length_protector = MakeRef(broker(), factory()->string_length_protector()); - string_length_protector.CacheAsProtector(); + string_length_protector.CacheAsProtector(broker()); - if (string_length_protector.value().AsSmi() == + if (string_length_protector.value(broker()).AsSmi() == Protectors::kProtectorValid) { // We can just deoptimize if the {length} is out-of-bounds. Besides // generating a shorter code sequence than the version below, this @@ -842,7 +868,8 @@ Reduction JSTypedLowering::ReduceJSEqual(Node* node) { // then ObjectIsUndetectable(left) // else ReferenceEqual(left, right) #define __ gasm. - JSGraphAssembler gasm(jsgraph(), jsgraph()->zone(), BranchSemantics::kJS); + JSGraphAssembler gasm(broker(), jsgraph(), jsgraph()->zone(), + BranchSemantics::kJS); gasm.InitializeEffectControl(r.effect(), r.control()); auto lhs = TNode<Object>::UncheckedCast(r.left()); @@ -911,6 +938,7 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node) { } NumberOperationHint hint; + BigIntOperationHint hint_bigint; if (r.BothInputsAre(Type::Signed32()) || r.BothInputsAre(Type::Unsigned32())) { return r.ChangeToPureOperator(simplified()->NumberEqual()); @@ -926,6 +954,11 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node) { simplified()->SpeculativeNumberEqual(hint), Type::Boolean()); } else if (r.BothInputsAre(Type::Number())) { return r.ChangeToPureOperator(simplified()->NumberEqual()); + } else if (r.GetCompareBigIntOperationHint(&hint_bigint)) { + DCHECK(hint_bigint == BigIntOperationHint::kBigInt || + hint_bigint == BigIntOperationHint::kBigInt64); + return r.ChangeToSpeculativeOperator( + simplified()->SpeculativeBigIntEqual(hint_bigint), Type::Boolean()); } else if (r.IsReceiverCompareOperation()) { // For strict equality, it's enough to know that one input is a Receiver, // as a strict equality comparison with a Receiver can only yield true if @@ -995,7 +1028,7 @@ Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { HeapObjectMatcher m(input); if (m.HasResolvedValue() && m.Ref(broker()).IsString()) { StringRef input_value = m.Ref(broker()).AsString(); - base::Optional<double> number = input_value.ToNumber(); + base::Optional<double> number = input_value.ToNumber(broker()); if (!number.has_value()) return NoChange(); return Replace(jsgraph()->Constant(number.value())); } @@ -1003,7 +1036,7 @@ Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { if (input_type.IsHeapConstant()) { HeapObjectRef input_value = input_type.AsHeapConstant()->Ref(); double value; - if (input_value.OddballToNumber().To(&value)) { + if (input_value.OddballToNumber(broker()).To(&value)) { return Replace(jsgraph()->Constant(value)); } } @@ -1044,6 +1077,39 @@ Reduction JSTypedLowering::ReduceJSToNumber(Node* node) { return NoChange(); } +Reduction JSTypedLowering::ReduceJSToBigInt(Node* node) { + // TODO(panq): Reduce constant inputs. + Node* const input = node->InputAt(0); + Type const input_type = NodeProperties::GetType(input); + if (input_type.Is(Type::BigInt())) { + ReplaceWithValue(node, input); + return Changed(input); + } + return NoChange(); +} + +Reduction JSTypedLowering::ReduceJSToBigIntConvertNumber(Node* node) { + // TODO(panq): Reduce constant inputs. + Node* const input = node->InputAt(0); + Type const input_type = NodeProperties::GetType(input); + if (input_type.Is(Type::BigInt())) { + ReplaceWithValue(node, input); + return Changed(input); + } else if (input_type.Is(Type::Signed32OrMinusZero()) || + input_type.Is(Type::Unsigned32OrMinusZero())) { + RelaxEffectsAndControls(node); + node->TrimInputCount(1); + Type node_type = NodeProperties::GetType(node); + NodeProperties::SetType( + node, + Type::Intersect(node_type, Type::SignedBigInt64(), graph()->zone())); + NodeProperties::ChangeOp(node, + simplified()->Integral32OrMinusZeroToBigInt()); + return Changed(node); + } + return NoChange(); +} + Reduction JSTypedLowering::ReduceJSToNumeric(Node* node) { Node* const input = NodeProperties::GetValueInput(node, 0); Type const input_type = NodeProperties::GetType(input); @@ -1170,8 +1236,8 @@ Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { JSLoadNamedNode n(node); Node* receiver = n.object(); Type receiver_type = NodeProperties::GetType(receiver); - NameRef name = NamedAccessOf(node->op()).name(broker()); - NameRef length_str = MakeRef(broker(), factory()->length_string()); + NameRef name = NamedAccessOf(node->op()).name(); + NameRef length_str = broker()->length_string(); // Optimize "length" property of strings. if (name.equals(length_str) && receiver_type.Is(Type::String())) { Node* value = graph()->NewNode(simplified()->StringLength(), receiver); @@ -1437,8 +1503,10 @@ Node* JSTypedLowering::BuildGetModuleCell(Node* node) { if (module_type.IsHeapConstant()) { SourceTextModuleRef module_constant = module_type.AsHeapConstant()->Ref().AsSourceTextModule(); - base::Optional<CellRef> cell_constant = module_constant.GetCell(cell_index); - if (cell_constant.has_value()) return jsgraph()->Constant(*cell_constant); + OptionalCellRef cell_constant = + module_constant.GetCell(broker(), cell_index); + if (cell_constant.has_value()) + return jsgraph()->Constant(*cell_constant, broker()); } FieldAccess field_access; @@ -1540,8 +1608,8 @@ void ReduceBuiltin(JSGraph* jsgraph, Node* node, Builtin builtin, int arity, DCHECK(Builtins::IsCpp(builtin)); const bool has_builtin_exit_frame = true; - Node* stub = jsgraph->CEntryStubConstant( - 1, SaveFPRegsMode::kIgnore, ArgvMode::kStack, has_builtin_exit_frame); + Node* stub = + jsgraph->CEntryStubConstant(1, ArgvMode::kStack, has_builtin_exit_frame); node->ReplaceInput(0, stub); const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver; @@ -1587,7 +1655,7 @@ Reduction JSTypedLowering::ReduceJSConstructForwardVarargs(Node* node) { target_type.AsHeapConstant()->Ref().IsJSFunction()) { // Only optimize [[Construct]] here if {function} is a Constructor. JSFunctionRef function = target_type.AsHeapConstant()->Ref().AsJSFunction(); - if (!function.map().is_constructor()) return NoChange(); + if (!function.map(broker()).is_constructor()) return NoChange(); // Patch {node} to an indirect call via ConstructFunctionForwardVarargs. Callable callable = CodeFactory::ConstructFunctionForwardVarargs(isolate()); node->InsertInput(graph()->zone(), 0, @@ -1619,11 +1687,11 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) { JSFunctionRef function = target_type.AsHeapConstant()->Ref().AsJSFunction(); // Only optimize [[Construct]] here if {function} is a Constructor. - if (!function.map().is_constructor()) return NoChange(); + if (!function.map(broker()).is_constructor()) return NoChange(); // Patch {node} to an indirect call via the {function}s construct stub. Callable callable = Builtins::CallableFor( - isolate(), function.shared().construct_as_builtin() + isolate(), function.shared(broker()).construct_as_builtin() ? Builtin::kJSBuiltinsConstructStub : Builtin::kJSConstructStubGeneric); static_assert(JSConstructNode::TargetIndex() == 0); @@ -1693,20 +1761,20 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { } // Check if we know the SharedFunctionInfo of {target}. - base::Optional<JSFunctionRef> function; - base::Optional<SharedFunctionInfoRef> shared; + OptionalJSFunctionRef function; + OptionalSharedFunctionInfoRef shared; if (target_type.IsHeapConstant() && target_type.AsHeapConstant()->Ref().IsJSFunction()) { function = target_type.AsHeapConstant()->Ref().AsJSFunction(); - shared = function->shared(); + shared = function->shared(broker()); } else if (target->opcode() == IrOpcode::kJSCreateClosure) { CreateClosureParameters const& ccp = JSCreateClosureNode{target}.Parameters(); - shared = ccp.shared_info(broker()); + shared = ccp.shared_info(); } else if (target->opcode() == IrOpcode::kCheckClosure) { FeedbackCellRef cell = MakeRef(broker(), FeedbackCellOf(target->op())); - shared = cell.shared_function_info(); + shared = cell.shared_function_info(broker()); } if (shared.has_value()) { @@ -1726,12 +1794,13 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { // require data from a foreign native context. if (is_sloppy(shared->language_mode()) && !shared->native() && !receiver_type.Is(Type::Receiver())) { - if (!function.has_value() || !function->native_context().equals( + if (!function.has_value() || !function->native_context(broker()).equals( broker()->target_native_context())) { return NoChange(); } - Node* global_proxy = - jsgraph()->Constant(function->native_context().global_proxy_object()); + Node* global_proxy = jsgraph()->Constant( + function->native_context(broker()).global_proxy_object(broker()), + broker()); receiver = effect = graph()->NewNode(simplified()->ConvertReceiver(convert_mode), receiver, global_proxy, effect, control); @@ -2395,6 +2464,10 @@ Reduction JSTypedLowering::Reduce(Node* node) { case IrOpcode::kJSToNumber: case IrOpcode::kJSToNumberConvertBigInt: return ReduceJSToNumber(node); + case IrOpcode::kJSToBigInt: + return ReduceJSToBigInt(node); + case IrOpcode::kJSToBigIntConvertNumber: + return ReduceJSToBigIntConvertNumber(node); case IrOpcode::kJSToNumeric: return ReduceJSToNumeric(node); case IrOpcode::kJSToString: |