Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: src/compiler/typer.cc

Issue 1410953006: [turbofan] Properly type field access to stable heap object maps. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/typer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/typer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698