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