diff options
Diffstat (limited to 'deps/v8/src/compiler/typer.cc')
-rw-r--r-- | deps/v8/src/compiler/typer.cc | 186 |
1 files changed, 139 insertions, 47 deletions
diff --git a/deps/v8/src/compiler/typer.cc b/deps/v8/src/compiler/typer.cc index 7ef20e7fae..248de5a0d5 100644 --- a/deps/v8/src/compiler/typer.cc +++ b/deps/v8/src/compiler/typer.cc @@ -34,13 +34,13 @@ class Typer::Decorator final : public GraphDecorator { Typer* const typer_; }; -Typer::Typer(JSHeapBroker* js_heap_broker, Flags flags, Graph* graph) +Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph) : flags_(flags), graph_(graph), decorator_(nullptr), cache_(TypeCache::Get()), - js_heap_broker_(js_heap_broker), - operation_typer_(js_heap_broker, zone()) { + broker_(broker), + operation_typer_(broker, zone()) { singleton_false_ = operation_typer_.singleton_false(); singleton_true_ = operation_typer_.singleton_true(); @@ -59,7 +59,8 @@ class Typer::Visitor : public Reducer { explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars) : typer_(typer), induction_vars_(induction_vars), - weakened_nodes_(typer->zone()) {} + weakened_nodes_(typer->zone()), + remembered_types_(typer->zone()) {} const char* reducer_name() const override { return "Typer"; } @@ -205,6 +206,8 @@ class Typer::Visitor : public Reducer { Typer* typer_; LoopVariableOptimizer* induction_vars_; ZoneSet<NodeId> weakened_nodes_; + // TODO(tebbi): remove once chromium:906567 is resolved. + ZoneUnorderedMap<std::pair<Node*, int>, Type> remembered_types_; #define DECLARE_METHOD(x) inline Type Type##x(Node* node); DECLARE_METHOD(Start) @@ -328,7 +331,52 @@ class Typer::Visitor : public Reducer { current = Weaken(node, current, previous); } - CHECK(previous.Is(current)); + if (V8_UNLIKELY(!previous.Is(current))) { + AllowHandleDereference allow; + std::ostringstream ostream; + node->Print(ostream); + + if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) { + ostream << "Previous UpdateType run (inputs first):"; + for (int i = 0; i < 3; ++i) { + ostream << " "; + if (remembered_types_[{node, i}].IsInvalid()) { + ostream << "untyped"; + } else { + remembered_types_[{node, i}].PrintTo(ostream); + } + } + + ostream << "\nCurrent (output) type: "; + previous.PrintTo(ostream); + + ostream << "\nThis UpdateType run (inputs first):"; + for (int i = 0; i < 2; ++i) { + ostream << " "; + Node* input = NodeProperties::GetValueInput(node, i); + if (NodeProperties::IsTyped(input)) { + NodeProperties::GetType(input).PrintTo(ostream); + } else { + ostream << "untyped"; + } + } + ostream << " "; + current.PrintTo(ostream); + ostream << "\n"; + } + + FATAL("UpdateType error for node %s", ostream.str().c_str()); + } + + if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) { + for (int i = 0; i < 2; ++i) { + Node* input = NodeProperties::GetValueInput(node, i); + remembered_types_[{node, i}] = NodeProperties::IsTyped(input) + ? NodeProperties::GetType(input) + : Type::Invalid(); + } + remembered_types_[{node, 2}] = current; + } NodeProperties::SetType(node, current); if (!current.Is(previous)) { @@ -337,6 +385,16 @@ class Typer::Visitor : public Reducer { } return NoChange(); } else { + if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) { + for (int i = 0; i < 2; ++i) { + Node* input = NodeProperties::GetValueInput(node, i); + remembered_types_[{node, i}] = NodeProperties::IsTyped(input) + ? NodeProperties::GetType(input) + : Type::Invalid(); + } + remembered_types_[{node, 2}] = current; + } + // No previous type, simply update the type. NodeProperties::SetType(node, current); return Changed(node); @@ -407,10 +465,12 @@ Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t, if (lhs_is_number && rhs_is_number) { return f(lhs, rhs, t); } - if (lhs_is_number || rhs_is_number) { + // In order to maintain monotonicity, the following two conditions are + // intentionally asymmetric. + if (lhs_is_number) { return Type::Number(); } - if (lhs.Is(Type::BigInt()) || rhs.Is(Type::BigInt())) { + if (lhs.Is(Type::BigInt())) { return Type::BigInt(); } return Type::Numeric(); @@ -439,7 +499,7 @@ Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) { Type Typer::Visitor::BitwiseNot(Type type, Typer* t) { type = ToNumeric(type, t); if (type.Is(Type::Number())) { - return NumberBitwiseXor(type, t->cache_.kSingletonMinusOne, t); + return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t); } return Type::Numeric(); } @@ -447,7 +507,7 @@ Type Typer::Visitor::BitwiseNot(Type type, Typer* t) { Type Typer::Visitor::Decrement(Type type, Typer* t) { type = ToNumeric(type, t); if (type.Is(Type::Number())) { - return NumberSubtract(type, t->cache_.kSingletonOne, t); + return NumberSubtract(type, t->cache_->kSingletonOne, t); } return Type::Numeric(); } @@ -455,7 +515,7 @@ Type Typer::Visitor::Decrement(Type type, Typer* t) { Type Typer::Visitor::Increment(Type type, Typer* t) { type = ToNumeric(type, t); if (type.Is(Type::Number())) { - return NumberAdd(type, t->cache_.kSingletonOne, t); + return NumberAdd(type, t->cache_->kSingletonOne, t); } return Type::Numeric(); } @@ -463,7 +523,7 @@ Type Typer::Visitor::Increment(Type type, Typer* t) { Type Typer::Visitor::Negate(Type type, Typer* t) { type = ToNumeric(type, t); if (type.Is(Type::Number())) { - return NumberMultiply(type, t->cache_.kSingletonMinusOne, t); + return NumberMultiply(type, t->cache_->kSingletonMinusOne, t); } return Type::Numeric(); } @@ -486,13 +546,13 @@ Type Typer::Visitor::ToBoolean(Type type, Typer* t) { Type Typer::Visitor::ToInteger(Type type, Typer* t) { // ES6 section 7.1.4 ToInteger ( argument ) type = ToNumber(type, t); - if (type.Is(t->cache_.kIntegerOrMinusZero)) return type; - if (type.Is(t->cache_.kIntegerOrMinusZeroOrNaN)) { + if (type.Is(t->cache_->kIntegerOrMinusZero)) return type; + if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) { return Type::Union( - Type::Intersect(type, t->cache_.kIntegerOrMinusZero, t->zone()), - t->cache_.kSingletonZero, t->zone()); + Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()), + t->cache_->kSingletonZero, t->zone()); } - return t->cache_.kIntegerOrMinusZero; + return t->cache_->kIntegerOrMinusZero; } @@ -691,7 +751,7 @@ Type Typer::Visitor::TypeParameter(Node* node) { return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone()); } } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) { - return Type::Range(0.0, Code::kMaxArguments, typer_->zone()); + return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone()); } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) { return Type::OtherInternal(); } @@ -754,8 +814,8 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { // We only handle integer induction variables (otherwise ranges // do not apply and we cannot do anything). - if (!initial_type.Is(typer_->cache_.kInteger) || - !increment_type.Is(typer_->cache_.kInteger)) { + if (!initial_type.Is(typer_->cache_->kInteger) || + !increment_type.Is(typer_->cache_->kInteger)) { // Fallback to normal phi typing, but ensure monotonicity. // (Unfortunately, without baking in the previous type, monotonicity might // be violated because we might not yet have retyped the incrementing @@ -771,7 +831,7 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { // If we do not have enough type information for the initial value or // the increment, just return the initial value's type. if (initial_type.IsNone() || - increment_type.Is(typer_->cache_.kSingletonZero)) { + increment_type.Is(typer_->cache_->kSingletonZero)) { return initial_type; } @@ -802,7 +862,7 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { for (auto bound : induction_var->upper_bounds()) { Type bound_type = TypeOrNone(bound.bound); // If the type is not an integer, just skip the bound. - if (!bound_type.Is(typer_->cache_.kInteger)) continue; + if (!bound_type.Is(typer_->cache_->kInteger)) continue; // If the type is not inhabited, then we can take the initial value. if (bound_type.IsNone()) { max = initial_type.Max(); @@ -822,7 +882,7 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { for (auto bound : induction_var->lower_bounds()) { Type bound_type = TypeOrNone(bound.bound); // If the type is not an integer, just skip the bound. - if (!bound_type.Is(typer_->cache_.kInteger)) continue; + if (!bound_type.Is(typer_->cache_->kInteger)) continue; // If the type is not inhabited, then we can take the initial value. if (bound_type.IsNone()) { min = initial_type.Min(); @@ -839,7 +899,7 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { } else { // Shortcut: If the increment can be both positive and negative, // the variable can go arbitrarily far, so just return integer. - return typer_->cache_.kInteger; + return typer_->cache_->kInteger; } if (FLAG_trace_turbo_loop) { StdoutStream{} << std::setprecision(10) << "Loop (" @@ -1170,6 +1230,10 @@ Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) { return Type::OtherObject(); } +Type Typer::Visitor::TypeJSCreateAsyncFunctionObject(Node* node) { + return Type::OtherObject(); +} + Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) { return Type::OtherObject(); } @@ -1275,7 +1339,7 @@ Type Typer::Visitor::Weaken(Node* node, Type current_type, Type previous_type) { STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); // If the types have nothing to do with integers, return the types. - Type const integer = typer_->cache_.kInteger; + Type const integer = typer_->cache_->kInteger; if (!previous_type.Maybe(integer)) { return current_type; } @@ -1436,7 +1500,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kMathCeil: case BuiltinFunctionId::kMathRound: case BuiltinFunctionId::kMathTrunc: - return t->cache_.kIntegerOrMinusZeroOrNaN; + return t->cache_->kIntegerOrMinusZeroOrNaN; // Unary math functions. case BuiltinFunctionId::kMathAbs: case BuiltinFunctionId::kMathExp: @@ -1460,7 +1524,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kMathTan: return Type::Number(); case BuiltinFunctionId::kMathSign: - return t->cache_.kMinusOneToOneOrMinusZeroOrNaN; + return t->cache_->kMinusOneToOneOrMinusZeroOrNaN; // Binary math functions. case BuiltinFunctionId::kMathAtan2: case BuiltinFunctionId::kMathPow: @@ -1470,29 +1534,29 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kMathImul: return Type::Signed32(); case BuiltinFunctionId::kMathClz32: - return t->cache_.kZeroToThirtyTwo; + return t->cache_->kZeroToThirtyTwo; // Date functions. case BuiltinFunctionId::kDateNow: - return t->cache_.kTimeValueType; + return t->cache_->kTimeValueType; case BuiltinFunctionId::kDateGetDate: - return t->cache_.kJSDateDayType; + return t->cache_->kJSDateDayType; case BuiltinFunctionId::kDateGetDay: - return t->cache_.kJSDateWeekdayType; + return t->cache_->kJSDateWeekdayType; case BuiltinFunctionId::kDateGetFullYear: - return t->cache_.kJSDateYearType; + return t->cache_->kJSDateYearType; case BuiltinFunctionId::kDateGetHours: - return t->cache_.kJSDateHourType; + return t->cache_->kJSDateHourType; case BuiltinFunctionId::kDateGetMilliseconds: return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(), t->zone()); case BuiltinFunctionId::kDateGetMinutes: - return t->cache_.kJSDateMinuteType; + return t->cache_->kJSDateMinuteType; case BuiltinFunctionId::kDateGetMonth: - return t->cache_.kJSDateMonthType; + return t->cache_->kJSDateMonthType; case BuiltinFunctionId::kDateGetSeconds: - return t->cache_.kJSDateSecondType; + return t->cache_->kJSDateSecondType; case BuiltinFunctionId::kDateGetTime: - return t->cache_.kJSDateValueType; + return t->cache_->kJSDateValueType; // Symbol functions. case BuiltinFunctionId::kSymbolConstructor: @@ -1517,7 +1581,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kNumberParseFloat: return Type::Number(); case BuiltinFunctionId::kNumberParseInt: - return t->cache_.kIntegerOrMinusZeroOrNaN; + return t->cache_->kIntegerOrMinusZeroOrNaN; case BuiltinFunctionId::kNumberToString: return Type::String(); @@ -1602,7 +1666,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kArrayMap: return Type::Receiver(); case BuiltinFunctionId::kArrayPush: - return t->cache_.kPositiveSafeInteger; + return t->cache_->kPositiveSafeInteger; case BuiltinFunctionId::kArrayReverse: case BuiltinFunctionId::kArraySlice: return Type::Receiver(); @@ -1611,7 +1675,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kArraySplice: return Type::Receiver(); case BuiltinFunctionId::kArrayUnshift: - return t->cache_.kPositiveSafeInteger; + return t->cache_->kPositiveSafeInteger; // ArrayBuffer functions. case BuiltinFunctionId::kArrayBufferIsView: @@ -1629,6 +1693,17 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { case BuiltinFunctionId::kObjectToString: return Type::String(); + case BuiltinFunctionId::kPromiseAll: + return Type::Receiver(); + case BuiltinFunctionId::kPromisePrototypeThen: + return Type::Receiver(); + case BuiltinFunctionId::kPromiseRace: + return Type::Receiver(); + case BuiltinFunctionId::kPromiseReject: + return Type::Receiver(); + case BuiltinFunctionId::kPromiseResolve: + return Type::Receiver(); + // RegExp functions. case BuiltinFunctionId::kRegExpCompile: return Type::OtherObject(); @@ -1762,7 +1837,7 @@ Type Typer::Visitor::TypeJSForInPrepare(Node* node) { Type const cache_type = Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone()); Type const cache_array = Type::OtherInternal(); - Type const cache_length = typer_->cache_.kFixedArrayLengthType; + Type const cache_length = typer_->cache_->kFixedArrayLengthType; return Type::Tuple(cache_type, cache_array, cache_length, zone()); } @@ -1796,6 +1871,18 @@ Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); } Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); } +Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) { + return Type::OtherObject(); +} + +Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) { + return Type::OtherObject(); +} + +Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) { + return Type::OtherObject(); +} + Type Typer::Visitor::TypeJSFulfillPromise(Node* node) { return Type::Undefined(); } @@ -1925,7 +2012,7 @@ Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) { } Type Typer::Visitor::TypeStringCharCodeAt(Node* node) { - return typer_->cache_.kUint16; + return typer_->cache_->kUint16; } Type Typer::Visitor::TypeStringCodePointAt(Node* node) { @@ -1945,13 +2032,13 @@ Type Typer::Visitor::TypeStringIndexOf(Node* node) { } Type Typer::Visitor::TypeStringLength(Node* node) { - return typer_->cache_.kStringLengthType; + return typer_->cache_->kStringLengthType; } Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); } Type Typer::Visitor::TypePoisonIndex(Node* node) { - return Type::Union(Operand(node, 0), typer_->cache_.kSingletonZero, zone()); + return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone()); } Type Typer::Visitor::TypeCheckBounds(Node* node) { @@ -1984,6 +2071,11 @@ Type Typer::Visitor::TypeCheckReceiver(Node* node) { return Type::Intersect(arg, Type::Receiver(), zone()); } +Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) { + Type arg = Operand(node, 0); + return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone()); +} + Type Typer::Visitor::TypeCheckSmi(Node* node) { Type arg = Operand(node, 0); return Type::Intersect(arg, Type::SignedSmall(), zone()); @@ -2047,7 +2139,7 @@ Type Typer::Visitor::TypeLoadTypedElement(Node* node) { switch (ExternalArrayTypeOf(node->op())) { #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \ case kExternal##ElemType##Array: \ - return typer_->cache_.k##ElemType; + return typer_->cache_->k##ElemType; TYPED_ARRAYS(TYPED_ARRAY_CASE) #undef TYPED_ARRAY_CASE } @@ -2058,7 +2150,7 @@ Type Typer::Visitor::TypeLoadDataViewElement(Node* node) { switch (ExternalArrayTypeOf(node->op())) { #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \ case kExternal##ElemType##Array: \ - return typer_->cache_.k##ElemType; + return typer_->cache_->k##ElemType; TYPED_ARRAYS(TYPED_ARRAY_CASE) #undef TYPED_ARRAY_CASE } @@ -2172,7 +2264,7 @@ Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) { } Type Typer::Visitor::TypeArgumentsLength(Node* node) { - return TypeCache::Get().kArgumentsLengthType; + return TypeCache::Get()->kArgumentsLengthType; } Type Typer::Visitor::TypeArgumentsFrame(Node* node) { @@ -2210,7 +2302,7 @@ Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); } // Heap constants. Type Typer::Visitor::TypeConstant(Handle<Object> value) { - return Type::NewConstant(typer_->js_heap_broker(), value, zone()); + return Type::NewConstant(typer_->broker(), value, zone()); } } // namespace compiler |