Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_ACCESS_INFO_H_
6 : #define V8_COMPILER_ACCESS_INFO_H_
7 :
8 : #include <iosfwd>
9 :
10 : #include "src/field-index.h"
11 : #include "src/machine-type.h"
12 : #include "src/objects.h"
13 : #include "src/zone/zone-containers.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : // Forward declarations.
19 : class CompilationDependencies;
20 : class Factory;
21 :
22 : namespace compiler {
23 :
24 : // Forward declarations.
25 : class Type;
26 : class TypeCache;
27 :
28 : // Whether we are loading a property or storing to a property.
29 : // For a store during literal creation, do not walk up the prototype chain.
30 : enum class AccessMode { kLoad, kStore, kStoreInLiteral };
31 :
32 : std::ostream& operator<<(std::ostream&, AccessMode);
33 :
34 : typedef std::vector<Handle<Map>> MapList;
35 :
36 : // Mapping of transition source to transition target.
37 : typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
38 :
39 : // This class encapsulates all information required to access a certain element.
40 353422 : class ElementAccessInfo final {
41 : public:
42 : ElementAccessInfo();
43 : ElementAccessInfo(MapList const& receiver_maps, ElementsKind elements_kind);
44 :
45 : ElementsKind elements_kind() const { return elements_kind_; }
46 : MapList const& receiver_maps() const { return receiver_maps_; }
47 : MapTransitionList& transitions() { return transitions_; }
48 : MapTransitionList const& transitions() const { return transitions_; }
49 :
50 : private:
51 : ElementsKind elements_kind_;
52 : MapList receiver_maps_;
53 : MapTransitionList transitions_;
54 : };
55 :
56 : // This class encapsulates all information required to access a certain
57 : // object property, either on the object itself or on the prototype chain.
58 366432 : class PropertyAccessInfo final {
59 : public:
60 : enum Kind {
61 : kInvalid,
62 : kNotFound,
63 : kDataConstant,
64 : kDataField,
65 : kDataConstantField,
66 : kAccessorConstant
67 : };
68 :
69 : static PropertyAccessInfo NotFound(MapList const& receiver_maps,
70 : MaybeHandle<JSObject> holder);
71 : static PropertyAccessInfo DataConstant(MapList const& receiver_maps,
72 : Handle<Object> constant,
73 : MaybeHandle<JSObject> holder);
74 : static PropertyAccessInfo DataField(
75 : PropertyConstness constness, MapList const& receiver_maps,
76 : FieldIndex field_index, MachineRepresentation field_representation,
77 : Type* field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
78 : MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
79 : MaybeHandle<Map> transition_map = MaybeHandle<Map>());
80 : static PropertyAccessInfo AccessorConstant(MapList const& receiver_maps,
81 : Handle<Object> constant,
82 : MaybeHandle<JSObject> holder);
83 :
84 : PropertyAccessInfo();
85 :
86 : bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
87 : Zone* zone) WARN_UNUSED_RESULT;
88 :
89 90462 : bool IsNotFound() const { return kind() == kNotFound; }
90 1110 : bool IsDataConstant() const { return kind() == kDataConstant; }
91 : bool IsDataField() const { return kind() == kDataField; }
92 : // TODO(ishell): rename to IsDataConstant() once constant field tracking
93 : // is done.
94 : bool IsDataConstantField() const { return kind() == kDataConstantField; }
95 89323 : bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
96 :
97 : bool HasTransitionMap() const { return !transition_map().is_null(); }
98 :
99 : Kind kind() const { return kind_; }
100 110862 : MaybeHandle<JSObject> holder() const { return holder_; }
101 7307 : MaybeHandle<Map> transition_map() const { return transition_map_; }
102 : Handle<Object> constant() const { return constant_; }
103 : FieldIndex field_index() const { return field_index_; }
104 : Type* field_type() const { return field_type_; }
105 : MachineRepresentation field_representation() const {
106 : return field_representation_;
107 : }
108 7829 : MaybeHandle<Map> field_map() const { return field_map_; }
109 : MapList const& receiver_maps() const { return receiver_maps_; }
110 :
111 : private:
112 : PropertyAccessInfo(MaybeHandle<JSObject> holder,
113 : MapList const& receiver_maps);
114 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
115 : Handle<Object> constant, MapList const& receiver_maps);
116 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
117 : MaybeHandle<Map> transition_map, FieldIndex field_index,
118 : MachineRepresentation field_representation,
119 : Type* field_type, MaybeHandle<Map> field_map,
120 : MapList const& receiver_maps);
121 :
122 : Kind kind_;
123 : MapList receiver_maps_;
124 : Handle<Object> constant_;
125 : MaybeHandle<Map> transition_map_;
126 : MaybeHandle<JSObject> holder_;
127 : FieldIndex field_index_;
128 : MachineRepresentation field_representation_;
129 : Type* field_type_;
130 : MaybeHandle<Map> field_map_;
131 : };
132 :
133 :
134 : // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
135 : class AccessInfoFactory final {
136 : public:
137 : AccessInfoFactory(CompilationDependencies* dependencies,
138 : Handle<Context> native_context, Zone* zone);
139 :
140 : bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
141 : ElementAccessInfo* access_info);
142 : bool ComputeElementAccessInfos(MapHandleList const& maps,
143 : AccessMode access_mode,
144 : ZoneVector<ElementAccessInfo>* access_infos);
145 : bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
146 : AccessMode access_mode,
147 : PropertyAccessInfo* access_info);
148 : bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
149 : AccessMode access_mode,
150 : ZoneVector<PropertyAccessInfo>* access_infos);
151 :
152 : private:
153 : bool ConsolidateElementAccess(MapHandleList const& maps,
154 : AccessMode access_mode,
155 : ElementAccessInfo* access_info);
156 : bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
157 : PropertyAccessInfo* access_info);
158 : bool LookupTransition(Handle<Map> map, Handle<Name> name,
159 : MaybeHandle<JSObject> holder,
160 : PropertyAccessInfo* access_info);
161 :
162 : CompilationDependencies* dependencies() const { return dependencies_; }
163 : Factory* factory() const;
164 : Isolate* isolate() const { return isolate_; }
165 : Handle<Context> native_context() const { return native_context_; }
166 : Zone* zone() const { return zone_; }
167 :
168 : CompilationDependencies* const dependencies_;
169 : Handle<Context> const native_context_;
170 : Isolate* const isolate_;
171 : TypeCache const& type_cache_;
172 : Zone* const zone_;
173 :
174 : DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
175 : };
176 :
177 : } // namespace compiler
178 : } // namespace internal
179 : } // namespace v8
180 :
181 : #endif // V8_COMPILER_ACCESS_INFO_H_
|