OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/typer.h" | 5 #include "src/compiler/typer.h" |
6 | 6 |
7 #include "src/base/flags.h" | 7 #include "src/base/flags.h" |
8 #include "src/base/lazy-instance.h" | 8 #include "src/base/lazy-instance.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/compilation-dependencies.h" | |
10 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
11 #include "src/compiler/graph-reducer.h" | 12 #include "src/compiler/graph-reducer.h" |
12 #include "src/compiler/js-operator.h" | 13 #include "src/compiler/js-operator.h" |
13 #include "src/compiler/node.h" | 14 #include "src/compiler/node.h" |
14 #include "src/compiler/node-properties.h" | 15 #include "src/compiler/node-properties.h" |
15 #include "src/compiler/simplified-operator.h" | 16 #include "src/compiler/simplified-operator.h" |
16 #include "src/objects-inl.h" | 17 #include "src/objects-inl.h" |
17 #include "src/zone-type-cache.h" | 18 #include "src/zone-type-cache.h" |
18 | 19 |
19 namespace v8 { | 20 namespace v8 { |
(...skipping 10 matching lines...) Expand all Loading... | |
30 class Typer::Decorator final : public GraphDecorator { | 31 class Typer::Decorator final : public GraphDecorator { |
31 public: | 32 public: |
32 explicit Decorator(Typer* typer) : typer_(typer) {} | 33 explicit Decorator(Typer* typer) : typer_(typer) {} |
33 void Decorate(Node* node) final; | 34 void Decorate(Node* node) final; |
34 | 35 |
35 private: | 36 private: |
36 Typer* const typer_; | 37 Typer* const typer_; |
37 }; | 38 }; |
38 | 39 |
39 | 40 |
40 Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type) | 41 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, |
42 CompilationDependencies* dependencies, | |
43 Type::FunctionType* function_type) | |
41 : isolate_(isolate), | 44 : isolate_(isolate), |
42 graph_(graph), | 45 graph_(graph), |
46 flags_(flags), | |
47 dependencies_(dependencies), | |
43 function_type_(function_type), | 48 function_type_(function_type), |
44 decorator_(nullptr), | 49 decorator_(nullptr), |
45 cache_(kCache.Get()) { | 50 cache_(kCache.Get()) { |
46 Zone* zone = this->zone(); | 51 Zone* zone = this->zone(); |
47 Factory* const factory = isolate->factory(); | 52 Factory* const factory = isolate->factory(); |
48 | 53 |
49 Type* infinity = Type::Constant(factory->infinity_value(), zone); | 54 Type* infinity = Type::Constant(factory->infinity_value(), zone); |
50 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); | 55 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); |
51 // TODO(neis): Unfortunately, the infinities created in other places might | 56 // TODO(neis): Unfortunately, the infinities created in other places might |
52 // be different ones (eg the result of NewNumber in TypeNumberConstant). | 57 // be different ones (eg the result of NewNumber in TypeNumberConstant). |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 Node* operand_node = NodeProperties::GetValueInput(node, i); | 202 Node* operand_node = NodeProperties::GetValueInput(node, i); |
198 return TypeOrNone(operand_node); | 203 return TypeOrNone(operand_node); |
199 } | 204 } |
200 | 205 |
201 Type* WrapContextTypeForInput(Node* node); | 206 Type* WrapContextTypeForInput(Node* node); |
202 Type* Weaken(Node* node, Type* current_type, Type* previous_type); | 207 Type* Weaken(Node* node, Type* current_type, Type* previous_type); |
203 | 208 |
204 Zone* zone() { return typer_->zone(); } | 209 Zone* zone() { return typer_->zone(); } |
205 Isolate* isolate() { return typer_->isolate(); } | 210 Isolate* isolate() { return typer_->isolate(); } |
206 Graph* graph() { return typer_->graph(); } | 211 Graph* graph() { return typer_->graph(); } |
212 Typer::Flags flags() const { return typer_->flags(); } | |
213 CompilationDependencies* dependencies() const { | |
214 return typer_->dependencies(); | |
215 } | |
207 | 216 |
208 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } | 217 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } |
209 bool IsWeakened(NodeId node_id) { | 218 bool IsWeakened(NodeId node_id) { |
210 return weakened_nodes_.find(node_id) != weakened_nodes_.end(); | 219 return weakened_nodes_.find(node_id) != weakened_nodes_.end(); |
211 } | 220 } |
212 | 221 |
213 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); | 222 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); |
214 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); | 223 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); |
215 | 224 |
216 Type* TypeUnaryOp(Node* node, UnaryTyperFun); | 225 Type* TypeUnaryOp(Node* node, UnaryTyperFun); |
(...skipping 28 matching lines...) Expand all Loading... | |
245 | 254 |
246 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); | 255 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); |
247 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) | 256 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) |
248 #undef DECLARE_METHOD | 257 #undef DECLARE_METHOD |
249 | 258 |
250 static Type* JSUnaryNotTyper(Type*, Typer*); | 259 static Type* JSUnaryNotTyper(Type*, Typer*); |
251 static Type* JSTypeOfTyper(Type*, Typer*); | 260 static Type* JSTypeOfTyper(Type*, Typer*); |
252 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); | 261 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); |
253 static Type* JSCallFunctionTyper(Type*, Typer*); | 262 static Type* JSCallFunctionTyper(Type*, Typer*); |
254 | 263 |
264 static Type* ReferenceEqualTyper(Type*, Type*, Typer*); | |
265 | |
255 Reduction UpdateType(Node* node, Type* current) { | 266 Reduction UpdateType(Node* node, Type* current) { |
256 if (NodeProperties::IsTyped(node)) { | 267 if (NodeProperties::IsTyped(node)) { |
257 // Widen the type of a previously typed node. | 268 // Widen the type of a previously typed node. |
258 Type* previous = NodeProperties::GetType(node); | 269 Type* previous = NodeProperties::GetType(node); |
259 if (node->opcode() == IrOpcode::kPhi) { | 270 if (node->opcode() == IrOpcode::kPhi) { |
260 // Speed up termination in the presence of range types: | 271 // Speed up termination in the presence of range types: |
261 current = Weaken(node, current, previous); | 272 current = Weaken(node, current, previous); |
262 } | 273 } |
263 | 274 |
264 DCHECK(previous->Is(current)); | 275 DCHECK(previous->Is(current)); |
(...skipping 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1568 Type* Typer::Visitor::TypeNumberToUint32(Node* node) { | 1579 Type* Typer::Visitor::TypeNumberToUint32(Node* node) { |
1569 return TypeUnaryOp(node, NumberToUint32); | 1580 return TypeUnaryOp(node, NumberToUint32); |
1570 } | 1581 } |
1571 | 1582 |
1572 | 1583 |
1573 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { | 1584 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { |
1574 return TypeUnaryOp(node, ToNumber); | 1585 return TypeUnaryOp(node, ToNumber); |
1575 } | 1586 } |
1576 | 1587 |
1577 | 1588 |
1589 // static | |
1590 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { | |
1591 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
| |
1592 return Type::Boolean(); | |
1593 } | |
1594 | |
1595 | |
1578 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { | 1596 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { |
1579 return Type::Boolean(zone()); | 1597 return TypeBinaryOp(node, ReferenceEqualTyper); |
1580 } | 1598 } |
1581 | 1599 |
1582 | 1600 |
1583 Type* Typer::Visitor::TypeStringEqual(Node* node) { | 1601 Type* Typer::Visitor::TypeStringEqual(Node* node) { |
1584 return Type::Boolean(zone()); | 1602 return Type::Boolean(zone()); |
1585 } | 1603 } |
1586 | 1604 |
1587 | 1605 |
1588 Type* Typer::Visitor::TypeStringLessThan(Node* node) { | 1606 Type* Typer::Visitor::TypeStringLessThan(Node* node) { |
1589 return Type::Boolean(zone()); | 1607 return Type::Boolean(zone()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1660 Type* arg = Operand(node, 0); | 1678 Type* arg = Operand(node, 0); |
1661 // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean())); | 1679 // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean())); |
1662 return ChangeRepresentation(arg, Type::TaggedPointer(), zone()); | 1680 return ChangeRepresentation(arg, Type::TaggedPointer(), zone()); |
1663 } | 1681 } |
1664 | 1682 |
1665 | 1683 |
1666 Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } | 1684 Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } |
1667 | 1685 |
1668 | 1686 |
1669 Type* Typer::Visitor::TypeLoadField(Node* node) { | 1687 Type* Typer::Visitor::TypeLoadField(Node* node) { |
1670 return FieldAccessOf(node->op()).type; | 1688 FieldAccess const& access = FieldAccessOf(node->op()); |
1689 if (access.base_is_tagged == kTaggedBase && | |
1690 access.offset == HeapObject::kMapOffset) { | |
1691 // The type of LoadField[Map](o) is Constant(map) if map is stable and | |
1692 // either | |
1693 // (a) o has type Constant(object) and map == object->map, or | |
1694 // (b) o has type Class(map), | |
1695 // and either | |
1696 // (1) map cannot transition further, or | |
1697 // (2) deoptimization is enabled and we can add a code dependency on the | |
1698 // stability of map (to guard the Constant type information). | |
1699 DCHECK(Type::Internal()->Is(access.type)); | |
1700 Type* const object = Operand(node, 0); | |
1701 Handle<Map> object_map; | |
1702 if (object->IsConstant() && object->AsConstant()->Value()->IsHeapObject()) { | |
1703 object_map = | |
1704 handle(Handle<HeapObject>::cast(object->AsConstant()->Value())->map(), | |
1705 isolate()); | |
1706 } else if (object->IsClass()) { | |
1707 object_map = object->AsClass()->Map(); | |
1708 } else { | |
1709 return access.type; | |
1710 } | |
1711 if (object_map->is_stable()) { | |
1712 if (!object_map->CanTransition()) { | |
1713 return Type::Constant(object_map, zone()); | |
1714 } | |
1715 if (flags() & kDeoptimizationEnabled) { | |
1716 dependencies()->AssumeMapStable(object_map); | |
1717 return Type::Constant(object_map, zone()); | |
1718 } | |
1719 } | |
1720 } | |
1721 return access.type; | |
1671 } | 1722 } |
1672 | 1723 |
1673 | 1724 |
1674 Type* Typer::Visitor::TypeLoadBuffer(Node* node) { | 1725 Type* Typer::Visitor::TypeLoadBuffer(Node* node) { |
1675 // TODO(bmeurer): This typing is not yet correct. Since we can still access | 1726 // TODO(bmeurer): This typing is not yet correct. Since we can still access |
1676 // out of bounds, the type in the general case has to include Undefined. | 1727 // out of bounds, the type in the general case has to include Undefined. |
1677 switch (BufferAccessOf(node->op()).external_array_type()) { | 1728 switch (BufferAccessOf(node->op()).external_array_type()) { |
1678 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1729 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1679 case kExternal##Type##Array: \ | 1730 case kExternal##Type##Array: \ |
1680 return typer_->cache_.k##Type; | 1731 return typer_->cache_.k##Type; |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2106 } | 2157 } |
2107 if (Type::IsInteger(*value)) { | 2158 if (Type::IsInteger(*value)) { |
2108 return Type::Range(value->Number(), value->Number(), zone()); | 2159 return Type::Range(value->Number(), value->Number(), zone()); |
2109 } | 2160 } |
2110 return Type::Constant(value, zone()); | 2161 return Type::Constant(value, zone()); |
2111 } | 2162 } |
2112 | 2163 |
2113 } // namespace compiler | 2164 } // namespace compiler |
2114 } // namespace internal | 2165 } // namespace internal |
2115 } // namespace v8 | 2166 } // namespace v8 |
OLD | NEW |