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/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/compilation-dependencies.h" | |
10 #include "src/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
11 #include "src/compiler/graph-reducer.h" | 10 #include "src/compiler/graph-reducer.h" |
12 #include "src/compiler/js-operator.h" | 11 #include "src/compiler/js-operator.h" |
13 #include "src/compiler/loop-variable-optimizer.h" | 12 #include "src/compiler/loop-variable-optimizer.h" |
14 #include "src/compiler/node-properties.h" | 13 #include "src/compiler/node-properties.h" |
15 #include "src/compiler/node.h" | 14 #include "src/compiler/node.h" |
16 #include "src/compiler/operation-typer.h" | 15 #include "src/compiler/operation-typer.h" |
17 #include "src/compiler/simplified-operator.h" | 16 #include "src/compiler/simplified-operator.h" |
18 #include "src/objects-inl.h" | 17 #include "src/objects-inl.h" |
19 #include "src/type-cache.h" | 18 #include "src/type-cache.h" |
20 | 19 |
21 namespace v8 { | 20 namespace v8 { |
22 namespace internal { | 21 namespace internal { |
23 namespace compiler { | 22 namespace compiler { |
24 | 23 |
25 class Typer::Decorator final : public GraphDecorator { | 24 class Typer::Decorator final : public GraphDecorator { |
26 public: | 25 public: |
27 explicit Decorator(Typer* typer) : typer_(typer) {} | 26 explicit Decorator(Typer* typer) : typer_(typer) {} |
28 void Decorate(Node* node) final; | 27 void Decorate(Node* node) final; |
29 | 28 |
30 private: | 29 private: |
31 Typer* const typer_; | 30 Typer* const typer_; |
32 }; | 31 }; |
33 | 32 |
34 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, | 33 Typer::Typer(Isolate* isolate, Graph* graph) |
35 CompilationDependencies* dependencies) | |
36 : isolate_(isolate), | 34 : isolate_(isolate), |
37 graph_(graph), | 35 graph_(graph), |
38 flags_(flags), | |
39 dependencies_(dependencies), | |
40 decorator_(nullptr), | 36 decorator_(nullptr), |
41 cache_(TypeCache::Get()), | 37 cache_(TypeCache::Get()), |
42 operation_typer_(isolate, zone()) { | 38 operation_typer_(isolate, zone()) { |
43 Zone* zone = this->zone(); | 39 Zone* zone = this->zone(); |
44 Factory* const factory = isolate->factory(); | 40 Factory* const factory = isolate->factory(); |
45 | 41 |
46 Type* infinity = Type::Constant(factory->infinity_value(), zone); | 42 Type* infinity = Type::Constant(factory->infinity_value(), zone); |
47 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); | 43 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); |
48 // Unfortunately, the infinities created in other places might be different | 44 // Unfortunately, the infinities created in other places might be different |
49 // ones (eg the result of NewNumber in TypeNumberConstant). | 45 // ones (eg the result of NewNumber in TypeNumberConstant). |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 Node* operand_node = NodeProperties::GetValueInput(node, i); | 211 Node* operand_node = NodeProperties::GetValueInput(node, i); |
216 return TypeOrNone(operand_node); | 212 return TypeOrNone(operand_node); |
217 } | 213 } |
218 | 214 |
219 Type* WrapContextTypeForInput(Node* node); | 215 Type* WrapContextTypeForInput(Node* node); |
220 Type* Weaken(Node* node, Type* current_type, Type* previous_type); | 216 Type* Weaken(Node* node, Type* current_type, Type* previous_type); |
221 | 217 |
222 Zone* zone() { return typer_->zone(); } | 218 Zone* zone() { return typer_->zone(); } |
223 Isolate* isolate() { return typer_->isolate(); } | 219 Isolate* isolate() { return typer_->isolate(); } |
224 Graph* graph() { return typer_->graph(); } | 220 Graph* graph() { return typer_->graph(); } |
225 Typer::Flags flags() const { return typer_->flags(); } | |
226 CompilationDependencies* dependencies() const { | |
227 return typer_->dependencies(); | |
228 } | |
229 | 221 |
230 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } | 222 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } |
231 bool IsWeakened(NodeId node_id) { | 223 bool IsWeakened(NodeId node_id) { |
232 return weakened_nodes_.find(node_id) != weakened_nodes_.end(); | 224 return weakened_nodes_.find(node_id) != weakened_nodes_.end(); |
233 } | 225 } |
234 | 226 |
235 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); | 227 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); |
236 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); | 228 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); |
237 | 229 |
238 Type* TypeUnaryOp(Node* node, UnaryTyperFun); | 230 Type* TypeUnaryOp(Node* node, UnaryTyperFun); |
(...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 | 1882 |
1891 Type* Typer::Visitor::TypeStringFromCharCode(Node* node) { | 1883 Type* Typer::Visitor::TypeStringFromCharCode(Node* node) { |
1892 return TypeUnaryOp(node, StringFromCharCodeTyper); | 1884 return TypeUnaryOp(node, StringFromCharCodeTyper); |
1893 } | 1885 } |
1894 | 1886 |
1895 Type* Typer::Visitor::TypeCheckBounds(Node* node) { | 1887 Type* Typer::Visitor::TypeCheckBounds(Node* node) { |
1896 // TODO(bmeurer): We could do better here based on the limit. | 1888 // TODO(bmeurer): We could do better here based on the limit. |
1897 return Type::Unsigned31(); | 1889 return Type::Unsigned31(); |
1898 } | 1890 } |
1899 | 1891 |
| 1892 Type* Typer::Visitor::TypeCheckMaps(Node* node) { |
| 1893 UNREACHABLE(); |
| 1894 return nullptr; |
| 1895 } |
| 1896 |
1900 Type* Typer::Visitor::TypeCheckNumber(Node* node) { | 1897 Type* Typer::Visitor::TypeCheckNumber(Node* node) { |
1901 Type* arg = Operand(node, 0); | 1898 Type* arg = Operand(node, 0); |
1902 return Type::Intersect(arg, Type::Number(), zone()); | 1899 return Type::Intersect(arg, Type::Number(), zone()); |
1903 } | 1900 } |
1904 | 1901 |
1905 Type* Typer::Visitor::TypeCheckString(Node* node) { | 1902 Type* Typer::Visitor::TypeCheckString(Node* node) { |
1906 Type* arg = Operand(node, 0); | 1903 Type* arg = Operand(node, 0); |
1907 return Type::Intersect(arg, Type::String(), zone()); | 1904 return Type::Intersect(arg, Type::String(), zone()); |
1908 } | 1905 } |
1909 | 1906 |
(...skipping 30 matching lines...) Expand all Loading... |
1940 case CheckTaggedHoleMode::kNeverReturnHole: { | 1937 case CheckTaggedHoleMode::kNeverReturnHole: { |
1941 // We deoptimize in case of the hole. | 1938 // We deoptimize in case of the hole. |
1942 break; | 1939 break; |
1943 } | 1940 } |
1944 } | 1941 } |
1945 return type; | 1942 return type; |
1946 } | 1943 } |
1947 | 1944 |
1948 Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } | 1945 Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } |
1949 | 1946 |
1950 | 1947 Type* Typer::Visitor::TypeLoadField(Node* node) { |
1951 namespace { | 1948 return FieldAccessOf(node->op()).type; |
1952 | |
1953 MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) { | |
1954 if (object_type->IsConstant() && | |
1955 object_type->AsConstant()->Value()->IsHeapObject()) { | |
1956 Handle<Map> object_map( | |
1957 Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map()); | |
1958 if (object_map->is_stable()) return object_map; | |
1959 } else if (object_type->IsClass()) { | |
1960 Handle<Map> object_map = object_type->AsClass()->Map(); | |
1961 if (object_map->is_stable()) return object_map; | |
1962 } | |
1963 return MaybeHandle<Map>(); | |
1964 } | 1949 } |
1965 | 1950 |
1966 } // namespace | |
1967 | |
1968 | |
1969 Type* Typer::Visitor::TypeLoadField(Node* node) { | |
1970 FieldAccess const& access = FieldAccessOf(node->op()); | |
1971 if (access.base_is_tagged == kTaggedBase && | |
1972 access.offset == HeapObject::kMapOffset) { | |
1973 // The type of LoadField[Map](o) is Constant(map) if map is stable and | |
1974 // either | |
1975 // (a) o has type Constant(object) and map == object->map, or | |
1976 // (b) o has type Class(map), | |
1977 // and either | |
1978 // (1) map cannot transition further, or | |
1979 // (2) deoptimization is enabled and we can add a code dependency on the | |
1980 // stability of map (to guard the Constant type information). | |
1981 Type* const object = Operand(node, 0); | |
1982 if (object->Is(Type::None())) return Type::None(); | |
1983 Handle<Map> object_map; | |
1984 if (GetStableMapFromObjectType(object).ToHandle(&object_map)) { | |
1985 if (object_map->CanTransition()) { | |
1986 if (flags() & kDeoptimizationEnabled) { | |
1987 dependencies()->AssumeMapStable(object_map); | |
1988 } else { | |
1989 return access.type; | |
1990 } | |
1991 } | |
1992 Type* object_map_type = Type::Constant(object_map, zone()); | |
1993 DCHECK(object_map_type->Is(access.type)); | |
1994 return object_map_type; | |
1995 } | |
1996 } | |
1997 return access.type; | |
1998 } | |
1999 | |
2000 | |
2001 Type* Typer::Visitor::TypeLoadBuffer(Node* node) { | 1951 Type* Typer::Visitor::TypeLoadBuffer(Node* node) { |
2002 // TODO(bmeurer): This typing is not yet correct. Since we can still access | 1952 // TODO(bmeurer): This typing is not yet correct. Since we can still access |
2003 // out of bounds, the type in the general case has to include Undefined. | 1953 // out of bounds, the type in the general case has to include Undefined. |
2004 switch (BufferAccessOf(node->op()).external_array_type()) { | 1954 switch (BufferAccessOf(node->op()).external_array_type()) { |
2005 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \ | 1955 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \ |
2006 case kExternal##ElemType##Array: \ | 1956 case kExternal##ElemType##Array: \ |
2007 return Type::Union(typer_->cache_.k##ElemType, Type::Undefined(), zone()); | 1957 return Type::Union(typer_->cache_.k##ElemType, Type::Undefined(), zone()); |
2008 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1958 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2009 #undef TYPED_ARRAY_CASE | 1959 #undef TYPED_ARRAY_CASE |
2010 } | 1960 } |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2705 } | 2655 } |
2706 if (Type::IsInteger(*value)) { | 2656 if (Type::IsInteger(*value)) { |
2707 return Type::Range(value->Number(), value->Number(), zone()); | 2657 return Type::Range(value->Number(), value->Number(), zone()); |
2708 } | 2658 } |
2709 return Type::Constant(value, zone()); | 2659 return Type::Constant(value, zone()); |
2710 } | 2660 } |
2711 | 2661 |
2712 } // namespace compiler | 2662 } // namespace compiler |
2713 } // namespace internal | 2663 } // namespace internal |
2714 } // namespace v8 | 2664 } // namespace v8 |
OLD | NEW |