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