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/compiler/types.h"
11 : #include "src/feedback-vector.h"
12 : #include "src/field-index.h"
13 : #include "src/machine-type.h"
14 : #include "src/objects.h"
15 : #include "src/objects/map.h"
16 : #include "src/zone/zone-containers.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : // Forward declarations.
22 : class Factory;
23 :
24 : namespace compiler {
25 :
26 : // Forward declarations.
27 : class CompilationDependencies;
28 : class ElementAccessFeedback;
29 : class Type;
30 : class TypeCache;
31 :
32 : // Whether we are loading a property or storing to a property.
33 : // For a store during literal creation, do not walk up the prototype chain.
34 : enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas };
35 :
36 : std::ostream& operator<<(std::ostream&, AccessMode);
37 :
38 : // This class encapsulates all information required to access a certain element.
39 284015 : 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 24073 : MapHandles const& receiver_maps() const { return receiver_maps_; }
47 : MapHandles const& transition_sources() const { return transition_sources_; }
48 :
49 560 : void AddTransitionSource(Handle<Map> map) {
50 560 : CHECK_EQ(receiver_maps_.size(), 1);
51 560 : transition_sources_.push_back(map);
52 560 : }
53 :
54 : private:
55 : ElementsKind elements_kind_;
56 : MapHandles receiver_maps_;
57 : MapHandles transition_sources_;
58 : };
59 :
60 : // This class encapsulates all information required to access a certain
61 : // object property, either on the object itself or on the prototype chain.
62 1681936 : class PropertyAccessInfo final {
63 : public:
64 : enum Kind {
65 : kInvalid,
66 : kNotFound,
67 : kDataConstant,
68 : kDataField,
69 : kDataConstantField,
70 : kAccessorConstant,
71 : kModuleExport,
72 : kStringLength
73 : };
74 :
75 : static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
76 : MaybeHandle<JSObject> holder);
77 : static PropertyAccessInfo DataConstant(MapHandles const& receiver_maps,
78 : Handle<Object> constant,
79 : MaybeHandle<JSObject> holder);
80 : static PropertyAccessInfo DataField(
81 : PropertyConstness constness, MapHandles const& receiver_maps,
82 : FieldIndex field_index, MachineRepresentation field_representation,
83 : Type field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
84 : MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
85 : MaybeHandle<Map> transition_map = MaybeHandle<Map>());
86 : static PropertyAccessInfo AccessorConstant(MapHandles const& receiver_maps,
87 : Handle<Object> constant,
88 : MaybeHandle<JSObject> holder);
89 : static PropertyAccessInfo ModuleExport(MapHandles const& receiver_maps,
90 : Handle<Cell> cell);
91 : static PropertyAccessInfo StringLength(MapHandles const& receiver_maps);
92 :
93 : PropertyAccessInfo();
94 :
95 : bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
96 : Zone* zone) V8_WARN_UNUSED_RESULT;
97 :
98 : bool IsInvalid() const { return kind() == kInvalid; }
99 : bool IsNotFound() const { return kind() == kNotFound; }
100 : bool IsDataConstant() const { return kind() == kDataConstant; }
101 : bool IsDataField() const { return kind() == kDataField; }
102 : // TODO(ishell): rename to IsDataConstant() once constant field tracking
103 : // is done.
104 : bool IsDataConstantField() const { return kind() == kDataConstantField; }
105 : bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
106 : bool IsModuleExport() const { return kind() == kModuleExport; }
107 : bool IsStringLength() const { return kind() == kStringLength; }
108 :
109 : bool HasTransitionMap() const { return !transition_map().is_null(); }
110 :
111 : Kind kind() const { return kind_; }
112 : MaybeHandle<JSObject> holder() const { return holder_; }
113 : MaybeHandle<Map> transition_map() const { return transition_map_; }
114 : Handle<Object> constant() const { return constant_; }
115 : FieldIndex field_index() const { return field_index_; }
116 : Type field_type() const { return field_type_; }
117 : MachineRepresentation field_representation() const {
118 : return field_representation_;
119 : }
120 : MaybeHandle<Map> field_map() const { return field_map_; }
121 74545 : MapHandles const& receiver_maps() const { return receiver_maps_; }
122 : Handle<Cell> export_cell() const;
123 :
124 : private:
125 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
126 : MapHandles const& receiver_maps);
127 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
128 : Handle<Object> constant, MapHandles const& receiver_maps);
129 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
130 : MaybeHandle<Map> transition_map, FieldIndex field_index,
131 : MachineRepresentation field_representation,
132 : Type field_type, MaybeHandle<Map> field_map,
133 : MapHandles const& receiver_maps);
134 :
135 : Kind kind_;
136 : MapHandles receiver_maps_;
137 : Handle<Object> constant_;
138 : MaybeHandle<Map> transition_map_;
139 : MaybeHandle<JSObject> holder_;
140 : FieldIndex field_index_;
141 : MachineRepresentation field_representation_;
142 : Type field_type_;
143 : MaybeHandle<Map> field_map_;
144 : };
145 :
146 :
147 : // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
148 : class AccessInfoFactory final {
149 : public:
150 : AccessInfoFactory(JSHeapBroker* broker, CompilationDependencies* dependencies,
151 : Zone* zone);
152 :
153 : bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
154 : ElementAccessInfo* access_info) const;
155 : bool ComputeElementAccessInfos(
156 : FeedbackNexus nexus, MapHandles const& maps, AccessMode access_mode,
157 : ZoneVector<ElementAccessInfo>* access_infos) const;
158 :
159 : PropertyAccessInfo ComputePropertyAccessInfo(Handle<Map> map,
160 : Handle<Name> name,
161 : AccessMode access_mode) const;
162 : PropertyAccessInfo ComputePropertyAccessInfo(MapHandles const& maps,
163 : Handle<Name> name,
164 : AccessMode access_mode) const;
165 : void ComputePropertyAccessInfos(
166 : MapHandles const& maps, Handle<Name> name, AccessMode access_mode,
167 : ZoneVector<PropertyAccessInfo>* access_infos) const;
168 :
169 : // Merge as many of the given {infos} as possible. Return false iff
170 : // any of them was invalid.
171 : bool FinalizePropertyAccessInfos(
172 : ZoneVector<PropertyAccessInfo> infos, AccessMode access_mode,
173 : ZoneVector<PropertyAccessInfo>* result) const;
174 :
175 : private:
176 : bool ConsolidateElementLoad(ElementAccessFeedback const& processed,
177 : ElementAccessInfo* access_info) const;
178 : PropertyAccessInfo LookupSpecialFieldAccessor(Handle<Map> map,
179 : Handle<Name> name) const;
180 : PropertyAccessInfo LookupTransition(Handle<Map> map, Handle<Name> name,
181 : MaybeHandle<JSObject> holder) const;
182 : PropertyAccessInfo ComputeDataFieldAccessInfo(Handle<Map> receiver_map,
183 : Handle<Map> map,
184 : MaybeHandle<JSObject> holder,
185 : int number,
186 : AccessMode access_mode) const;
187 : PropertyAccessInfo ComputeAccessorDescriptorAccessInfo(
188 : Handle<Map> receiver_map, Handle<Name> name, Handle<Map> map,
189 : MaybeHandle<JSObject> holder, int number, AccessMode access_mode) const;
190 :
191 : CompilationDependencies* dependencies() const { return dependencies_; }
192 : JSHeapBroker* broker() const { return broker_; }
193 : Isolate* isolate() const { return broker()->isolate(); }
194 : Zone* zone() const { return zone_; }
195 :
196 : JSHeapBroker* const broker_;
197 : CompilationDependencies* const dependencies_;
198 : TypeCache const* const type_cache_;
199 : Zone* const zone_;
200 :
201 : DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
202 : };
203 :
204 : } // namespace compiler
205 : } // namespace internal
206 : } // namespace v8
207 :
208 : #endif // V8_COMPILER_ACCESS_INFO_H_
|