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/objects/map.h"
14 : #include "src/zone/zone-containers.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 :
19 : // Forward declarations.
20 : class CompilationDependencies;
21 : class Factory;
22 :
23 : namespace compiler {
24 :
25 : // Forward declarations.
26 : class Type;
27 : class TypeCache;
28 :
29 : // Whether we are loading a property or storing to a property.
30 : // For a store during literal creation, do not walk up the prototype chain.
31 : enum class AccessMode { kLoad, kStore, kStoreInLiteral };
32 :
33 : std::ostream& operator<<(std::ostream&, AccessMode);
34 :
35 : // Mapping of transition source to transition target.
36 : typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
37 :
38 : // This class encapsulates all information required to access a certain element.
39 356222 : class ElementAccessInfo final {
40 : public:
41 : ElementAccessInfo();
42 : ElementAccessInfo(MapHandles const& receiver_maps,
43 : ElementsKind elements_kind);
44 :
45 : ElementsKind elements_kind() const { return elements_kind_; }
46 : MapHandles 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 : MapHandles 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 473884 : class PropertyAccessInfo final {
59 : public:
60 : enum Kind {
61 : kInvalid,
62 : kNotFound,
63 : kDataConstant,
64 : kDataField,
65 : kDataConstantField,
66 : kAccessorConstant,
67 : kModuleExport
68 : };
69 :
70 : static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
71 : MaybeHandle<JSObject> holder);
72 : static PropertyAccessInfo DataConstant(MapHandles const& receiver_maps,
73 : Handle<Object> constant,
74 : MaybeHandle<JSObject> holder);
75 : static PropertyAccessInfo DataField(
76 : PropertyConstness constness, MapHandles const& receiver_maps,
77 : FieldIndex field_index, MachineRepresentation field_representation,
78 : Type* field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
79 : MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
80 : MaybeHandle<Map> transition_map = MaybeHandle<Map>());
81 : static PropertyAccessInfo AccessorConstant(MapHandles const& receiver_maps,
82 : Handle<Object> constant,
83 : MaybeHandle<JSObject> holder);
84 : static PropertyAccessInfo ModuleExport(MapHandles const& receiver_maps,
85 : Handle<Cell> cell);
86 :
87 : PropertyAccessInfo();
88 :
89 : bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
90 : Zone* zone) WARN_UNUSED_RESULT;
91 :
92 86671 : bool IsNotFound() const { return kind() == kNotFound; }
93 29531 : bool IsDataConstant() const { return kind() == kDataConstant; }
94 : bool IsDataField() const { return kind() == kDataField; }
95 : // TODO(ishell): rename to IsDataConstant() once constant field tracking
96 : // is done.
97 : bool IsDataConstantField() const { return kind() == kDataConstantField; }
98 : bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
99 : bool IsModuleExport() const { return kind() == kModuleExport; }
100 :
101 : bool HasTransitionMap() const { return !transition_map().is_null(); }
102 :
103 : Kind kind() const { return kind_; }
104 : MaybeHandle<JSObject> holder() const { return holder_; }
105 : MaybeHandle<Map> transition_map() const { return transition_map_; }
106 : Handle<Object> constant() const { return constant_; }
107 : FieldIndex field_index() const { return field_index_; }
108 : Type* field_type() const { return field_type_; }
109 : MachineRepresentation field_representation() const {
110 : return field_representation_;
111 : }
112 : MaybeHandle<Map> field_map() const { return field_map_; }
113 : MapHandles const& receiver_maps() const { return receiver_maps_; }
114 : Handle<Cell> export_cell() const;
115 :
116 : private:
117 : PropertyAccessInfo(MaybeHandle<JSObject> holder,
118 : MapHandles const& receiver_maps);
119 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
120 : Handle<Object> constant, MapHandles const& receiver_maps);
121 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
122 : MaybeHandle<Map> transition_map, FieldIndex field_index,
123 : MachineRepresentation field_representation,
124 : Type* field_type, MaybeHandle<Map> field_map,
125 : MapHandles const& receiver_maps);
126 :
127 : Kind kind_;
128 : MapHandles receiver_maps_;
129 : Handle<Object> constant_;
130 : MaybeHandle<Map> transition_map_;
131 : MaybeHandle<JSObject> holder_;
132 : FieldIndex field_index_;
133 : MachineRepresentation field_representation_;
134 : Type* field_type_;
135 : MaybeHandle<Map> field_map_;
136 : };
137 :
138 :
139 : // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
140 : class AccessInfoFactory final {
141 : public:
142 : AccessInfoFactory(CompilationDependencies* dependencies,
143 : Handle<Context> native_context, Zone* zone);
144 :
145 : bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
146 : ElementAccessInfo* access_info);
147 : bool ComputeElementAccessInfos(MapHandles const& maps, AccessMode access_mode,
148 : ZoneVector<ElementAccessInfo>* access_infos);
149 : bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
150 : AccessMode access_mode,
151 : PropertyAccessInfo* access_info);
152 : bool ComputePropertyAccessInfos(MapHandles const& maps, Handle<Name> name,
153 : AccessMode access_mode,
154 : ZoneVector<PropertyAccessInfo>* access_infos);
155 :
156 : private:
157 : bool ConsolidateElementLoad(MapHandles const& maps,
158 : ElementAccessInfo* access_info);
159 : bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
160 : PropertyAccessInfo* access_info);
161 : bool LookupTransition(Handle<Map> map, Handle<Name> name,
162 : MaybeHandle<JSObject> holder,
163 : PropertyAccessInfo* access_info);
164 :
165 : CompilationDependencies* dependencies() const { return dependencies_; }
166 : Factory* factory() const;
167 : Isolate* isolate() const { return isolate_; }
168 : Handle<Context> native_context() const { return native_context_; }
169 : Zone* zone() const { return zone_; }
170 :
171 : CompilationDependencies* const dependencies_;
172 : Handle<Context> const native_context_;
173 : Isolate* const isolate_;
174 : TypeCache const& type_cache_;
175 : Zone* const zone_;
176 :
177 : DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
178 : };
179 :
180 : } // namespace compiler
181 : } // namespace internal
182 : } // namespace v8
183 :
184 : #endif // V8_COMPILER_ACCESS_INFO_H_
|