summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/typer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/typer.cc')
-rw-r--r--deps/v8/src/compiler/typer.cc186
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