v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
access-info.h
Go to the documentation of this file.
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 <optional>
9
13
14namespace v8 {
15namespace internal {
16
17// Forward declarations.
18class Factory;
19
20namespace compiler {
21
22// Forward declarations.
23class CompilationDependencies;
24class CompilationDependency;
25class ElementAccessFeedback;
26class JSHeapBroker;
27class TypeCache;
28struct ConstFieldInfo;
29
30std::ostream& operator<<(std::ostream&, AccessMode);
31
32// This class encapsulates all information required to access a certain element.
56
57// This class encapsulates all information required to access a certain
58// object property, either on the object itself or on the prototype chain.
59class PropertyAccessInfo final {
60 public:
74
75 static PropertyAccessInfo NotFound(Zone* zone, MapRef receiver_map,
76 OptionalJSObjectRef holder);
78 JSHeapBroker* broker, Zone* zone, MapRef receiver_map,
79 ZoneVector<CompilationDependency const*>&& unrecorded_dependencies,
81 Type field_type, MapRef field_owner_map, OptionalMapRef field_map,
82 OptionalJSObjectRef holder, OptionalMapRef transition_map);
84 Zone* zone, MapRef receiver_map,
85 ZoneVector<CompilationDependency const*>&& unrecorded_dependencies,
87 Type field_type, MapRef field_owner_map, OptionalMapRef field_map,
88 OptionalJSObjectRef holder, OptionalMapRef transition_map);
90 Zone* zone, MapRef receiver_map, OptionalJSObjectRef holder,
91 OptionalObjectRef constant, OptionalJSObjectRef api_holder);
92 static PropertyAccessInfo ModuleExport(Zone* zone, MapRef receiver_map,
93 CellRef cell);
94 static PropertyAccessInfo StringLength(Zone* zone, MapRef receiver_map);
96 MapRef receiver_map);
97 static PropertyAccessInfo TypedArrayLength(Zone* zone, MapRef receiver_map);
98 static PropertyAccessInfo Invalid(Zone* zone);
100 Zone* zone, MapRef receiver_map, JSObjectRef holder,
101 InternalIndex dict_index, NameRef name);
103 Zone* zone, MapRef receiver_map, OptionalJSObjectRef holder,
104 ObjectRef constant, OptionalJSObjectRef api_holder, NameRef name);
105
106 bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
108
110
111 bool IsInvalid() const { return kind() == kInvalid; }
112 bool IsNotFound() const { return kind() == kNotFound; }
113 bool IsDataField() const { return kind() == kDataField; }
114 bool IsFastDataConstant() const { return kind() == kFastDataConstant; }
116 return kind() == kFastAccessorConstant;
117 }
118 bool IsModuleExport() const { return kind() == kModuleExport; }
119 bool IsStringLength() const { return kind() == kStringLength; }
120 bool IsStringWrapperLength() const { return kind() == kStringWrapperLength; }
121 bool IsTypedArrayLength() const { return kind() == kTypedArrayLength; }
128
129 bool HasTransitionMap() const { return transition_map().has_value(); }
135
136 Kind kind() const { return kind_; }
137
138 // The object where the property definition was found.
139 OptionalJSObjectRef holder() const {
140 // TODO(neis): There was a CHECK here that tries to protect against
141 // using the access info without recording its dependencies first.
142 // Find a more suitable place for it.
143 return holder_;
144 }
145 OptionalMapRef transition_map() const {
147 return transition_map_;
148 }
149 OptionalObjectRef constant() const {
150 DCHECK_IMPLIES(constant_.has_value(),
153 return constant_;
154 }
157 return field_index_;
158 }
159
160 Type field_type() const {
162 return field_type_;
163 }
168 OptionalMapRef field_map() const {
170 return field_map_;
171 }
175
180
181 NameRef name() const {
183 return name_.value();
184 }
185
190
191 private:
192 explicit PropertyAccessInfo(Zone* zone);
193 PropertyAccessInfo(Zone* zone, Kind kind, OptionalJSObjectRef holder,
195 PropertyAccessInfo(Zone* zone, Kind kind, OptionalJSObjectRef holder,
196 OptionalObjectRef constant, OptionalJSObjectRef api_holder,
197 OptionalNameRef name,
199 PropertyAccessInfo(Kind kind, OptionalJSObjectRef holder,
200 OptionalMapRef transition_map, FieldIndex field_index,
202 MapRef field_owner_map, OptionalMapRef field_map,
205 PropertyAccessInfo(Zone* zone, Kind kind, OptionalJSObjectRef holder,
208
209 // Members used for fast and dictionary mode holders:
212 OptionalObjectRef constant_;
213 OptionalJSObjectRef holder_;
214 OptionalJSObjectRef api_holder_;
215
216 // Members only used for fast mode holders:
218 OptionalMapRef transition_map_;
222 OptionalMapRef field_owner_map_;
223 OptionalMapRef field_map_;
224
225 // Members only used for dictionary mode holders:
227 OptionalNameRef name_;
228
229 // Members only used for kTypedArrayLength:
231};
232
233// Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
234class AccessInfoFactory final {
235 public:
237
238 std::optional<ElementAccessInfo> ComputeElementAccessInfo(
239 MapRef map, AccessMode access_mode) const;
241 ElementAccessFeedback const& feedback,
242 ZoneVector<ElementAccessInfo>* access_infos) const;
243
245 AccessMode access_mode) const;
246
248 MapRef receiver_map, NameRef name, JSObjectRef holder,
249 InternalIndex dict_index, AccessMode access_mode,
250 PropertyDetails details) const;
251
252 // Merge as many of the given {infos} as possible and record any dependencies.
253 // Return false iff any of them was invalid, in which case no dependencies are
254 // recorded.
255 // TODO(neis): Make access_mode part of access info?
259
260 // Merge the given {infos} to a single one and record any dependencies. If the
261 // merge is not possible, the result has kind {kInvalid} and no dependencies
262 // are recorded.
264 ZoneVector<PropertyAccessInfo> infos, AccessMode access_mode) const;
265
266 private:
267 std::optional<ElementAccessInfo> ConsolidateElementLoad(
268 ElementAccessFeedback const& feedback) const;
271 OptionalJSObjectRef holder,
272 PropertyAttributes attrs) const;
274 NameRef name,
275 OptionalJSObjectRef holder,
276 InternalIndex descriptor,
277 AccessMode access_mode) const;
279 MapRef receiver_map, NameRef name, MapRef map, OptionalJSObjectRef holder,
280 InternalIndex descriptor, AccessMode access_mode) const;
281
285
287 AccessMode access_mode,
289
290 bool TryLoadPropertyDetails(MapRef map, OptionalJSObjectRef maybe_holder,
291 NameRef name, InternalIndex* index_out,
292 PropertyDetails* details_out) const;
293
295 JSHeapBroker* broker() const { return broker_; }
296 Isolate* isolate() const;
297 Zone* zone() const { return zone_; }
298
300 TypeCache const* const type_cache_;
301 Zone* const zone_;
302
305};
306
307} // namespace compiler
308} // namespace internal
309} // namespace v8
310
311#endif // V8_COMPILER_ACCESS_INFO_H_
bool ComputeElementAccessInfos(ElementAccessFeedback const &feedback, ZoneVector< ElementAccessInfo > *access_infos) const
AccessInfoFactory(JSHeapBroker *broker, Zone *zone)
std::optional< ElementAccessInfo > ConsolidateElementLoad(ElementAccessFeedback const &feedback) const
PropertyAccessInfo LookupTransition(MapRef map, NameRef name, OptionalJSObjectRef holder, PropertyAttributes attrs) const
bool FinalizePropertyAccessInfos(ZoneVector< PropertyAccessInfo > infos, AccessMode access_mode, ZoneVector< PropertyAccessInfo > *result) const
PropertyAccessInfo ComputeDictionaryProtoAccessInfo(MapRef receiver_map, NameRef name, JSObjectRef holder, InternalIndex dict_index, AccessMode access_mode, PropertyDetails details) const
PropertyAccessInfo LookupSpecialFieldAccessor(MapRef map, NameRef name) const
bool TryLoadPropertyDetails(MapRef map, OptionalJSObjectRef maybe_holder, NameRef name, InternalIndex *index_out, PropertyDetails *details_out) const
void MergePropertyAccessInfos(ZoneVector< PropertyAccessInfo > infos, AccessMode access_mode, ZoneVector< PropertyAccessInfo > *result) const
AccessInfoFactory(const AccessInfoFactory &)=delete
PropertyAccessInfo Invalid() const
PropertyAccessInfo FinalizePropertyAccessInfosAsOne(ZoneVector< PropertyAccessInfo > infos, AccessMode access_mode) const
PropertyAccessInfo ComputePropertyAccessInfo(MapRef map, NameRef name, AccessMode access_mode) const
AccessInfoFactory & operator=(const AccessInfoFactory &)=delete
std::optional< ElementAccessInfo > ComputeElementAccessInfo(MapRef map, AccessMode access_mode) const
PropertyAccessInfo ComputeDataFieldAccessInfo(MapRef receiver_map, MapRef map, NameRef name, OptionalJSObjectRef holder, InternalIndex descriptor, AccessMode access_mode) const
PropertyAccessInfo ComputeAccessorDescriptorAccessInfo(MapRef receiver_map, NameRef name, MapRef map, OptionalJSObjectRef holder, InternalIndex descriptor, AccessMode access_mode) const
CompilationDependencies * dependencies() const
ZoneVector< MapRef > lookup_start_object_maps_
Definition access-info.h:53
ZoneVector< MapRef > const & lookup_start_object_maps() const
Definition access-info.h:39
ElementAccessInfo(ZoneVector< MapRef > &&lookup_start_object_maps, ElementsKind elements_kind, Zone *zone)
ZoneVector< MapRef > const & transition_sources() const
Definition access-info.h:42
Representation field_representation() const
static PropertyAccessInfo TypedArrayLength(Zone *zone, MapRef receiver_map)
static PropertyAccessInfo FastAccessorConstant(Zone *zone, MapRef receiver_map, OptionalJSObjectRef holder, OptionalObjectRef constant, OptionalJSObjectRef api_holder)
static PropertyAccessInfo NotFound(Zone *zone, MapRef receiver_map, OptionalJSObjectRef holder)
bool Merge(PropertyAccessInfo const *that, AccessMode access_mode, Zone *zone) V8_WARN_UNUSED_RESULT
static PropertyAccessInfo StringWrapperLength(Zone *zone, MapRef receiver_map)
OptionalJSObjectRef holder() const
void set_elements_kind(ElementsKind elements_kind)
static PropertyAccessInfo DictionaryProtoDataConstant(Zone *zone, MapRef receiver_map, JSObjectRef holder, InternalIndex dict_index, NameRef name)
ZoneVector< CompilationDependency const * > unrecorded_dependencies_
ZoneVector< MapRef > const & lookup_start_object_maps() const
static PropertyAccessInfo StringLength(Zone *zone, MapRef receiver_map)
static PropertyAccessInfo Invalid(Zone *zone)
static PropertyAccessInfo ModuleExport(Zone *zone, MapRef receiver_map, CellRef cell)
static PropertyAccessInfo DataField(JSHeapBroker *broker, Zone *zone, MapRef receiver_map, ZoneVector< CompilationDependency const * > &&unrecorded_dependencies, FieldIndex field_index, Representation field_representation, Type field_type, MapRef field_owner_map, OptionalMapRef field_map, OptionalJSObjectRef holder, OptionalMapRef transition_map)
void RecordDependencies(CompilationDependencies *dependencies)
static PropertyAccessInfo FastDataConstant(Zone *zone, MapRef receiver_map, ZoneVector< CompilationDependency const * > &&unrecorded_dependencies, FieldIndex field_index, Representation field_representation, Type field_type, MapRef field_owner_map, OptionalMapRef field_map, OptionalJSObjectRef holder, OptionalMapRef transition_map)
static PropertyAccessInfo DictionaryProtoAccessorConstant(Zone *zone, MapRef receiver_map, OptionalJSObjectRef holder, ObjectRef constant, OptionalJSObjectRef api_holder, NameRef name)
JSHeapBroker * broker
ZoneVector< RpoNumber > & result
std::ostream & operator<<(std::ostream &os, AccessMode access_mode)
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671