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