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/objects.h"
12#include "src/zone-containers.h"
13
14namespace v8 {
15namespace internal {
16
17// Forward declarations.
18class CompilationDependencies;
19class Factory;
20class TypeCache;
21
22
23namespace compiler {
24
25// Whether we are loading a property or storing to a property.
26enum class AccessMode { kLoad, kStore };
27
28std::ostream& operator<<(std::ostream&, AccessMode);
29
30
31// Mapping of transition source to transition target.
32typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
33
34
35// This class encapsulates all information required to access a certain element.
36class ElementAccessInfo final {
37 public:
38  ElementAccessInfo();
39  ElementAccessInfo(Type* receiver_type, ElementsKind elements_kind,
40                    MaybeHandle<JSObject> holder);
41
42  MaybeHandle<JSObject> holder() const { return holder_; }
43  ElementsKind elements_kind() const { return elements_kind_; }
44  Type* receiver_type() const { return receiver_type_; }
45  MapTransitionList& transitions() { return transitions_; }
46  MapTransitionList const& transitions() const { return transitions_; }
47
48 private:
49  ElementsKind elements_kind_;
50  MaybeHandle<JSObject> holder_;
51  Type* receiver_type_;
52  MapTransitionList transitions_;
53};
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.
58class PropertyAccessInfo final {
59 public:
60  enum Kind { kInvalid, kNotFound, kDataConstant, kDataField };
61
62  static PropertyAccessInfo NotFound(Type* receiver_type,
63                                     MaybeHandle<JSObject> holder);
64  static PropertyAccessInfo DataConstant(Type* receiver_type,
65                                         Handle<Object> constant,
66                                         MaybeHandle<JSObject> holder);
67  static PropertyAccessInfo DataField(
68      Type* receiver_type, FieldIndex field_index, Type* field_type,
69      MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
70      MaybeHandle<Map> transition_map = MaybeHandle<Map>());
71
72  PropertyAccessInfo();
73
74  bool IsNotFound() const { return kind() == kNotFound; }
75  bool IsDataConstant() const { return kind() == kDataConstant; }
76  bool IsDataField() const { return kind() == kDataField; }
77
78  bool HasTransitionMap() const { return !transition_map().is_null(); }
79
80  Kind kind() const { return kind_; }
81  MaybeHandle<JSObject> holder() const { return holder_; }
82  MaybeHandle<Map> transition_map() const { return transition_map_; }
83  Handle<Object> constant() const { return constant_; }
84  FieldIndex field_index() const { return field_index_; }
85  Type* field_type() const { return field_type_; }
86  Type* receiver_type() const { return receiver_type_; }
87
88 private:
89  PropertyAccessInfo(MaybeHandle<JSObject> holder, Type* receiver_type);
90  PropertyAccessInfo(MaybeHandle<JSObject> holder, Handle<Object> constant,
91                     Type* receiver_type);
92  PropertyAccessInfo(MaybeHandle<JSObject> holder,
93                     MaybeHandle<Map> transition_map, FieldIndex field_index,
94                     Type* field_type, Type* receiver_type);
95
96  Kind kind_;
97  Type* receiver_type_;
98  Handle<Object> constant_;
99  MaybeHandle<Map> transition_map_;
100  MaybeHandle<JSObject> holder_;
101  FieldIndex field_index_;
102  Type* field_type_;
103};
104
105
106// Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
107class AccessInfoFactory final {
108 public:
109  AccessInfoFactory(CompilationDependencies* dependencies,
110                    Handle<Context> native_context, Zone* zone);
111
112  bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
113                                ElementAccessInfo* access_info);
114  bool ComputeElementAccessInfos(MapHandleList const& maps,
115                                 AccessMode access_mode,
116                                 ZoneVector<ElementAccessInfo>* access_infos);
117  bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
118                                 AccessMode access_mode,
119                                 PropertyAccessInfo* access_info);
120  bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
121                                  AccessMode access_mode,
122                                  ZoneVector<PropertyAccessInfo>* access_infos);
123
124 private:
125  bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
126                                  PropertyAccessInfo* access_info);
127  bool LookupTransition(Handle<Map> map, Handle<Name> name,
128                        MaybeHandle<JSObject> holder,
129                        PropertyAccessInfo* access_info);
130
131  CompilationDependencies* dependencies() const { return dependencies_; }
132  Factory* factory() const;
133  Isolate* isolate() const { return isolate_; }
134  Handle<Context> native_context() const { return native_context_; }
135  Zone* zone() const { return zone_; }
136
137  CompilationDependencies* const dependencies_;
138  Handle<Context> const native_context_;
139  Isolate* const isolate_;
140  TypeCache const& type_cache_;
141  Zone* const zone_;
142
143  DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
144};
145
146}  // namespace compiler
147}  // namespace internal
148}  // namespace v8
149
150#endif  // V8_COMPILER_ACCESS_INFO_H_
151