• Home
  • History
  • Annotate
  • 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 enum class AccessMode { kLoad, kStore };
30 
31 std::ostream& operator<<(std::ostream&, AccessMode);
32 
33 typedef std::vector<Handle<Map>> MapList;
34 
35 // Mapping of transition source to transition target.
36 typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
37 
38 // This class encapsulates all information required to access a certain element.
39 class ElementAccessInfo final {
40  public:
41   ElementAccessInfo();
42   ElementAccessInfo(MapList const& receiver_maps, ElementsKind elements_kind);
43 
elements_kind()44   ElementsKind elements_kind() const { return elements_kind_; }
receiver_maps()45   MapList const& receiver_maps() const { return receiver_maps_; }
transitions()46   MapTransitionList& transitions() { return transitions_; }
transitions()47   MapTransitionList const& transitions() const { return transitions_; }
48 
49  private:
50   ElementsKind elements_kind_;
51   MapList receiver_maps_;
52   MapTransitionList transitions_;
53 };
54 
55 // This class encapsulates all information required to access a certain
56 // object property, either on the object itself or on the prototype chain.
57 class PropertyAccessInfo final {
58  public:
59   enum Kind {
60     kInvalid,
61     kNotFound,
62     kDataConstant,
63     kDataField,
64     kAccessorConstant,
65     kGeneric
66   };
67 
68   static PropertyAccessInfo NotFound(MapList const& receiver_maps,
69                                      MaybeHandle<JSObject> holder);
70   static PropertyAccessInfo DataConstant(MapList const& receiver_maps,
71                                          Handle<Object> constant,
72                                          MaybeHandle<JSObject> holder);
73   static PropertyAccessInfo DataField(
74       MapList const& receiver_maps, FieldIndex field_index,
75       MachineRepresentation field_representation, Type* field_type,
76       MaybeHandle<Map> field_map = MaybeHandle<Map>(),
77       MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
78       MaybeHandle<Map> transition_map = MaybeHandle<Map>());
79   static PropertyAccessInfo AccessorConstant(MapList const& receiver_maps,
80                                              Handle<Object> constant,
81                                              MaybeHandle<JSObject> holder);
82   static PropertyAccessInfo Generic(MapList const& receiver_maps);
83 
84   PropertyAccessInfo();
85 
86   bool Merge(PropertyAccessInfo const* that) WARN_UNUSED_RESULT;
87 
IsNotFound()88   bool IsNotFound() const { return kind() == kNotFound; }
IsDataConstant()89   bool IsDataConstant() const { return kind() == kDataConstant; }
IsDataField()90   bool IsDataField() const { return kind() == kDataField; }
IsAccessorConstant()91   bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
IsGeneric()92   bool IsGeneric() const { return kind() == kGeneric; }
93 
HasTransitionMap()94   bool HasTransitionMap() const { return !transition_map().is_null(); }
95 
kind()96   Kind kind() const { return kind_; }
holder()97   MaybeHandle<JSObject> holder() const { return holder_; }
transition_map()98   MaybeHandle<Map> transition_map() const { return transition_map_; }
constant()99   Handle<Object> constant() const { return constant_; }
field_index()100   FieldIndex field_index() const { return field_index_; }
field_type()101   Type* field_type() const { return field_type_; }
field_representation()102   MachineRepresentation field_representation() const {
103     return field_representation_;
104   }
field_map()105   MaybeHandle<Map> field_map() const { return field_map_; }
receiver_maps()106   MapList const& receiver_maps() const { return receiver_maps_; }
107 
108  private:
109   PropertyAccessInfo(MaybeHandle<JSObject> holder,
110                      MapList const& receiver_maps);
111   PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
112                      Handle<Object> constant, MapList const& receiver_maps);
113   PropertyAccessInfo(MaybeHandle<JSObject> holder,
114                      MaybeHandle<Map> transition_map, FieldIndex field_index,
115                      MachineRepresentation field_representation,
116                      Type* field_type, MaybeHandle<Map> field_map,
117                      MapList const& receiver_maps);
118 
119   Kind kind_;
120   MapList receiver_maps_;
121   Handle<Object> constant_;
122   MaybeHandle<Map> transition_map_;
123   MaybeHandle<JSObject> holder_;
124   FieldIndex field_index_;
125   MachineRepresentation field_representation_;
126   Type* field_type_;
127   MaybeHandle<Map> field_map_;
128 };
129 
130 
131 // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
132 class AccessInfoFactory final {
133  public:
134   AccessInfoFactory(CompilationDependencies* dependencies,
135                     Handle<Context> native_context, Zone* zone);
136 
137   bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
138                                 ElementAccessInfo* access_info);
139   bool ComputeElementAccessInfos(MapHandleList const& maps,
140                                  AccessMode access_mode,
141                                  ZoneVector<ElementAccessInfo>* access_infos);
142   bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
143                                  AccessMode access_mode,
144                                  PropertyAccessInfo* access_info);
145   bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
146                                   AccessMode access_mode,
147                                   ZoneVector<PropertyAccessInfo>* access_infos);
148 
149  private:
150   bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
151                                   PropertyAccessInfo* access_info);
152   bool LookupTransition(Handle<Map> map, Handle<Name> name,
153                         MaybeHandle<JSObject> holder,
154                         PropertyAccessInfo* access_info);
155 
dependencies()156   CompilationDependencies* dependencies() const { return dependencies_; }
157   Factory* factory() const;
isolate()158   Isolate* isolate() const { return isolate_; }
native_context()159   Handle<Context> native_context() const { return native_context_; }
zone()160   Zone* zone() const { return zone_; }
161 
162   CompilationDependencies* const dependencies_;
163   Handle<Context> const native_context_;
164   Isolate* const isolate_;
165   TypeCache const& type_cache_;
166   Zone* const zone_;
167 
168   DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
169 };
170 
171 }  // namespace compiler
172 }  // namespace internal
173 }  // namespace v8
174 
175 #endif  // V8_COMPILER_ACCESS_INFO_H_
176