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 : // Mapping of transition source to transition target.
37 : typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
38 :
39 : // This class encapsulates all information required to access a certain element.
40 297960 : class ElementAccessInfo final {
41 : public:
42 : ElementAccessInfo();
43 : ElementAccessInfo(MapHandles const& receiver_maps,
44 : ElementsKind elements_kind);
45 :
46 : ElementsKind elements_kind() const { return elements_kind_; }
47 : MapHandles const& receiver_maps() const { return receiver_maps_; }
48 : MapTransitionList& transitions() { return transitions_; }
49 : MapTransitionList const& transitions() const { return transitions_; }
50 :
51 : private:
52 : ElementsKind elements_kind_;
53 : MapHandles receiver_maps_;
54 : MapTransitionList transitions_;
55 : };
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.
59 544721 : class PropertyAccessInfo final {
60 : public:
61 : enum Kind {
62 : kInvalid,
63 : kNotFound,
64 : kDataConstant,
65 : kDataField,
66 : kDataConstantField,
67 : kAccessorConstant,
68 : kModuleExport,
69 : kStringLength
70 : };
71 :
72 : static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
73 : MaybeHandle<JSObject> holder);
74 : static PropertyAccessInfo DataConstant(MapHandles const& receiver_maps,
75 : Handle<Object> constant,
76 : MaybeHandle<JSObject> holder);
77 : static PropertyAccessInfo DataField(
78 : PropertyConstness constness, MapHandles const& receiver_maps,
79 : FieldIndex field_index, MachineRepresentation field_representation,
80 : Type field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
81 : MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
82 : MaybeHandle<Map> transition_map = MaybeHandle<Map>());
83 : static PropertyAccessInfo AccessorConstant(MapHandles const& receiver_maps,
84 : Handle<Object> constant,
85 : MaybeHandle<JSObject> holder);
86 : static PropertyAccessInfo ModuleExport(MapHandles const& receiver_maps,
87 : Handle<Cell> cell);
88 : static PropertyAccessInfo StringLength(MapHandles const& receiver_maps);
89 :
90 : PropertyAccessInfo();
91 :
92 : bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
93 : Zone* zone) V8_WARN_UNUSED_RESULT;
94 :
95 108513 : bool IsNotFound() const { return kind() == kNotFound; }
96 26125 : bool IsDataConstant() const { return kind() == kDataConstant; }
97 : bool IsDataField() const { return kind() == kDataField; }
98 : // TODO(ishell): rename to IsDataConstant() once constant field tracking
99 : // is done.
100 : bool IsDataConstantField() const { return kind() == kDataConstantField; }
101 : bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
102 : bool IsModuleExport() const { return kind() == kModuleExport; }
103 : bool IsStringLength() const { return kind() == kStringLength; }
104 :
105 : bool HasTransitionMap() const { return !transition_map().is_null(); }
106 :
107 : Kind kind() const { return kind_; }
108 : MaybeHandle<JSObject> holder() const { return holder_; }
109 : MaybeHandle<Map> transition_map() const { return transition_map_; }
110 : Handle<Object> constant() const { return constant_; }
111 : FieldIndex field_index() const { return field_index_; }
112 : Type field_type() const { return field_type_; }
113 : MachineRepresentation field_representation() const {
114 : return field_representation_;
115 : }
116 : MaybeHandle<Map> field_map() const { return field_map_; }
117 : MapHandles const& receiver_maps() const { return receiver_maps_; }
118 : Handle<Cell> export_cell() const;
119 :
120 : private:
121 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
122 : MapHandles const& receiver_maps);
123 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
124 : Handle<Object> constant, MapHandles const& receiver_maps);
125 : PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
126 : MaybeHandle<Map> transition_map, FieldIndex field_index,
127 : MachineRepresentation field_representation,
128 : Type field_type, MaybeHandle<Map> field_map,
129 : MapHandles const& receiver_maps);
130 :
131 : Kind kind_;
132 : MapHandles receiver_maps_;
133 : Handle<Object> constant_;
134 : MaybeHandle<Map> transition_map_;
135 : MaybeHandle<JSObject> holder_;
136 : FieldIndex field_index_;
137 : MachineRepresentation field_representation_;
138 : Type field_type_;
139 : MaybeHandle<Map> field_map_;
140 : };
141 :
142 :
143 : // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
144 : class AccessInfoFactory final {
145 : public:
146 : AccessInfoFactory(JSHeapBroker* broker, CompilationDependencies* dependencies,
147 :
148 : Handle<Context> native_context, Zone* zone);
149 :
150 : bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
151 : ElementAccessInfo* access_info);
152 : bool ComputeElementAccessInfos(MapHandles const& maps, AccessMode access_mode,
153 : ZoneVector<ElementAccessInfo>* access_infos);
154 : bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
155 : AccessMode access_mode,
156 : PropertyAccessInfo* access_info);
157 : bool ComputePropertyAccessInfo(MapHandles const& maps, Handle<Name> name,
158 : AccessMode access_mode,
159 : PropertyAccessInfo* access_info);
160 : bool ComputePropertyAccessInfos(MapHandles const& maps, Handle<Name> name,
161 : AccessMode access_mode,
162 : ZoneVector<PropertyAccessInfo>* access_infos);
163 :
164 : private:
165 : bool ConsolidateElementLoad(MapHandles const& maps,
166 : ElementAccessInfo* access_info);
167 : bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
168 : PropertyAccessInfo* access_info);
169 : bool LookupTransition(Handle<Map> map, Handle<Name> name,
170 : MaybeHandle<JSObject> holder,
171 : PropertyAccessInfo* access_info);
172 :
173 : CompilationDependencies* dependencies() const { return dependencies_; }
174 : JSHeapBroker* broker() const { return broker_; }
175 : Factory* factory() const;
176 : Isolate* isolate() const { return isolate_; }
177 : Handle<Context> native_context() const { return native_context_; }
178 : Zone* zone() const { return zone_; }
179 :
180 : JSHeapBroker* const broker_;
181 : CompilationDependencies* const dependencies_;
182 : Handle<Context> const native_context_;
183 : Isolate* const isolate_;
184 : TypeCache const* type_cache_;
185 : Zone* const zone_;
186 :
187 : DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
188 : };
189 :
190 : } // namespace compiler
191 : } // namespace internal
192 : } // namespace v8
193 :
194 : #endif // V8_COMPILER_ACCESS_INFO_H_
|