Chromium Code Reviews| Index: src/compiler/typer.cc |
| diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
| index 2430d40e00a5df787f9f1a0b4f737144af17e2ea..4c8dfc647d4e3d3a40b06b6c3700f215e35af815 100644 |
| --- a/src/compiler/typer.cc |
| +++ b/src/compiler/typer.cc |
| @@ -7,6 +7,7 @@ |
| #include "src/base/flags.h" |
| #include "src/base/lazy-instance.h" |
| #include "src/bootstrapper.h" |
| +#include "src/compilation-dependencies.h" |
| #include "src/compiler/common-operator.h" |
| #include "src/compiler/graph-reducer.h" |
| #include "src/compiler/js-operator.h" |
| @@ -37,9 +38,13 @@ class Typer::Decorator final : public GraphDecorator { |
| }; |
| -Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type) |
| +Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, |
| + CompilationDependencies* dependencies, |
| + Type::FunctionType* function_type) |
| : isolate_(isolate), |
| graph_(graph), |
| + flags_(flags), |
| + dependencies_(dependencies), |
| function_type_(function_type), |
| decorator_(nullptr), |
| cache_(kCache.Get()) { |
| @@ -204,6 +209,10 @@ class Typer::Visitor : public Reducer { |
| Zone* zone() { return typer_->zone(); } |
| Isolate* isolate() { return typer_->isolate(); } |
| Graph* graph() { return typer_->graph(); } |
| + Typer::Flags flags() const { return typer_->flags(); } |
| + CompilationDependencies* dependencies() const { |
| + return typer_->dependencies(); |
| + } |
| void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } |
| bool IsWeakened(NodeId node_id) { |
| @@ -252,6 +261,8 @@ class Typer::Visitor : public Reducer { |
| static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); |
| static Type* JSCallFunctionTyper(Type*, Typer*); |
| + static Type* ReferenceEqualTyper(Type*, Type*, Typer*); |
| + |
| Reduction UpdateType(Node* node, Type* current) { |
| if (NodeProperties::IsTyped(node)) { |
| // Widen the type of a previously typed node. |
| @@ -1575,8 +1586,15 @@ Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { |
| } |
| +// static |
| +Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| + if (lhs->Is(rhs) && rhs->Is(lhs)) return t->singleton_true_; |
|
rossberg
2015/10/26 11:44:19
I don't understand. This seems to say that if the
Benedikt Meurer
2015/10/26 11:46:39
Of course (similar to JSStrictEqualTyper). Thanks
|
| + return Type::Boolean(); |
| +} |
| + |
| + |
| Type* Typer::Visitor::TypeReferenceEqual(Node* node) { |
| - return Type::Boolean(zone()); |
| + return TypeBinaryOp(node, ReferenceEqualTyper); |
| } |
| @@ -1667,7 +1685,40 @@ Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } |
| Type* Typer::Visitor::TypeLoadField(Node* node) { |
| - return FieldAccessOf(node->op()).type; |
| + FieldAccess const& access = FieldAccessOf(node->op()); |
| + if (access.base_is_tagged == kTaggedBase && |
| + access.offset == HeapObject::kMapOffset) { |
| + // The type of LoadField[Map](o) is Constant(map) if map is stable and |
| + // either |
| + // (a) o has type Constant(object) and map == object->map, or |
| + // (b) o has type Class(map), |
| + // and either |
| + // (1) map cannot transition further, or |
| + // (2) deoptimization is enabled and we can add a code dependency on the |
| + // stability of map (to guard the Constant type information). |
| + DCHECK(Type::Internal()->Is(access.type)); |
| + Type* const object = Operand(node, 0); |
| + Handle<Map> object_map; |
| + if (object->IsConstant() && object->AsConstant()->Value()->IsHeapObject()) { |
| + object_map = |
| + handle(Handle<HeapObject>::cast(object->AsConstant()->Value())->map(), |
| + isolate()); |
| + } else if (object->IsClass()) { |
| + object_map = object->AsClass()->Map(); |
| + } else { |
| + return access.type; |
| + } |
| + if (object_map->is_stable()) { |
| + if (!object_map->CanTransition()) { |
| + return Type::Constant(object_map, zone()); |
| + } |
| + if (flags() & kDeoptimizationEnabled) { |
| + dependencies()->AssumeMapStable(object_map); |
| + return Type::Constant(object_map, zone()); |
| + } |
| + } |
| + } |
| + return access.type; |
| } |