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 276076 : 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 23773 : MapHandles const& receiver_maps() const { return receiver_maps_; }
47 : MapHandles const& transition_sources() const { return transition_sources_; }
48 :
49 570 : void AddTransitionSource(Handle<Map> map) {
50 570 : CHECK_EQ(receiver_maps_.size(), 1);
51 570 : transition_sources_.push_back(map);
52 570 : }
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 1366634 : 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 IsNotFound() const { return kind() == kNotFound; }
99 : bool IsDataConstant() const { return kind() == kDataConstant; }
100 : bool IsDataField() const { return kind() == kDataField; }
101 : // TODO(ishell): rename to IsDataConstant() once constant field tracking
102 : // is done.
103 : bool IsDataConstantField() const { return kind() == kDataConstantField; }
104 : bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
105 : bool IsModuleExport() const { return kind() == kModuleExport; }
106 : bool IsStringLength() const { return kind() == kStringLength; }
107 :
108 : bool HasTransitionMap() const { return !transition_map().is_null(); }
109 :
110 : Kind kind() const { return kind_; }
111 : MaybeHandle<JSObject> holder() const { return holder_; }
112 : MaybeHandle<Map> transition_map() const { return transition_map_; }
113 : Handle<Object> constant() const { return constant_; }
114 : FieldIndex field_index() const { return field_index_; }
115 : Type field_type() const { return field_type_; }
116 : MachineRepresentation field_representation() const {
117 : return field_representation_;
118 : }
119 : MaybeHandle<Map> field_map() const { return field_map_; }
120 72663 : MapHandles const& receiver_maps() const { return receiver_maps_; }
121 : Handle<Cell> export_cell() const;
122 :
123 : private:
124 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
125 : MapHandles const& receiver_maps);
126 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
127 : Handle<Object> constant, MapHandles const& receiver_maps);
128 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
129 : MaybeHandle<Map> transition_map, FieldIndex field_index,
130 : MachineRepresentation field_representation,
131 : Type field_type, MaybeHandle<Map> field_map,
132 : MapHandles const& receiver_maps);
133 :
134 : Kind kind_;
135 : MapHandles receiver_maps_;
136 : Handle<Object> constant_;
137 : MaybeHandle<Map> transition_map_;
138 : MaybeHandle<JSObject> holder_;
139 : FieldIndex field_index_;
140 : MachineRepresentation field_representation_;
141 : Type field_type_;
142 : MaybeHandle<Map> field_map_;
143 : };
144 :
145 :
146 : // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
147 : class AccessInfoFactory final {
148 : public:
149 : AccessInfoFactory(JSHeapBroker* broker, CompilationDependencies* dependencies,
150 : Zone* zone);
151 :
152 : bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
153 : ElementAccessInfo* access_info) const;
154 : bool ComputeElementAccessInfos(
155 : FeedbackNexus nexus, MapHandles const& maps, AccessMode access_mode,
156 : ZoneVector<ElementAccessInfo>* access_infos) const;
157 :
158 : bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
159 : AccessMode access_mode,
160 : PropertyAccessInfo* access_info) const;
161 : bool ComputePropertyAccessInfo(MapHandles const& maps, Handle<Name> name,
162 : AccessMode access_mode,
163 : PropertyAccessInfo* access_info) const;
164 : bool ComputePropertyAccessInfos(
165 : MapHandles const& maps, Handle<Name> name, AccessMode access_mode,
166 : ZoneVector<PropertyAccessInfo>* access_infos) const;
167 :
168 : private:
169 : bool ConsolidateElementLoad(ElementAccessFeedback const& processed,
170 : ElementAccessInfo* access_info) const;
171 : bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
172 : PropertyAccessInfo* access_info) const;
173 : bool LookupTransition(Handle<Map> map, Handle<Name> name,
174 : MaybeHandle<JSObject> holder,
175 : PropertyAccessInfo* access_info) const;
176 : bool ComputeDataFieldAccessInfo(Handle<Map> receiver_map, Handle<Map> map,
177 : MaybeHandle<JSObject> holder, int number,
178 : AccessMode access_mode,
179 : PropertyAccessInfo* access_info) const;
180 : bool ComputeAccessorDescriptorAccessInfo(
181 : Handle<Map> receiver_map, Handle<Name> name, Handle<Map> map,
182 : MaybeHandle<JSObject> holder, int number, AccessMode access_mode,
183 : PropertyAccessInfo* access_info) const;
184 :
185 : CompilationDependencies* dependencies() const { return dependencies_; }
186 : JSHeapBroker* broker() const { return broker_; }
187 : Isolate* isolate() const { return broker()->isolate(); }
188 : Zone* zone() const { return zone_; }
189 :
190 : JSHeapBroker* const broker_;
191 : CompilationDependencies* const dependencies_;
192 : TypeCache const* const type_cache_;
193 : Zone* const zone_;
194 :
195 : DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
196 : };
197 :
198 : } // namespace compiler
199 : } // namespace internal
200 : } // namespace v8
201 :
202 : #endif // V8_COMPILER_ACCESS_INFO_H_
|