access-info.h 6.98 KB
Newer Older
1 2 3 4
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_COMPILER_ACCESS_INFO_H_
#define V8_COMPILER_ACCESS_INFO_H_
7 8 9 10

#include <iosfwd>

#include "src/field-index.h"
11
#include "src/machine-type.h"
12
#include "src/objects.h"
13
#include "src/objects/map.h"
14
#include "src/zone/zone-containers.h"
15 16 17 18 19 20 21 22 23 24

namespace v8 {
namespace internal {

// Forward declarations.
class CompilationDependencies;
class Factory;

namespace compiler {

25
// Forward declarations.
26
class Type;
27 28
class TypeCache;

29
// Whether we are loading a property or storing to a property.
30 31
// For a store during literal creation, do not walk up the prototype chain.
enum class AccessMode { kLoad, kStore, kStoreInLiteral };
32

33 34
std::ostream& operator<<(std::ostream&, AccessMode);

35 36 37
// Mapping of transition source to transition target.
typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;

38 39 40 41
// This class encapsulates all information required to access a certain element.
class ElementAccessInfo final {
 public:
  ElementAccessInfo();
42 43
  ElementAccessInfo(MapHandles const& receiver_maps,
                    ElementsKind elements_kind);
44 45

  ElementsKind elements_kind() const { return elements_kind_; }
46
  MapHandles const& receiver_maps() const { return receiver_maps_; }
47 48
  MapTransitionList& transitions() { return transitions_; }
  MapTransitionList const& transitions() const { return transitions_; }
49 50 51

 private:
  ElementsKind elements_kind_;
52
  MapHandles receiver_maps_;
53
  MapTransitionList transitions_;
54
};
55 56 57 58 59

// This class encapsulates all information required to access a certain
// object property, either on the object itself or on the prototype chain.
class PropertyAccessInfo final {
 public:
60 61 62 63 64
  enum Kind {
    kInvalid,
    kNotFound,
    kDataConstant,
    kDataField,
65
    kDataConstantField,
66 67
    kAccessorConstant,
    kModuleExport
68
  };
69

70
  static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
71
                                     MaybeHandle<JSObject> holder);
72
  static PropertyAccessInfo DataConstant(MapHandles const& receiver_maps,
73
                                         Handle<Object> constant,
74
                                         MaybeHandle<JSObject> holder);
75
  static PropertyAccessInfo DataField(
76
      PropertyConstness constness, MapHandles const& receiver_maps,
77 78
      FieldIndex field_index, MachineRepresentation field_representation,
      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(MapHandles const& receiver_maps,
82 83
                                             Handle<Object> constant,
                                             MaybeHandle<JSObject> holder);
84 85
  static PropertyAccessInfo ModuleExport(MapHandles const& receiver_maps,
                                         Handle<Cell> cell);
86 87 88

  PropertyAccessInfo();

89 90
  bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
             Zone* zone) WARN_UNUSED_RESULT;
91

92
  bool IsNotFound() const { return kind() == kNotFound; }
93 94
  bool IsDataConstant() const { return kind() == kDataConstant; }
  bool IsDataField() const { return kind() == kDataField; }
95 96 97
  // TODO(ishell): rename to IsDataConstant() once constant field tracking
  // is done.
  bool IsDataConstantField() const { return kind() == kDataConstantField; }
98
  bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
99
  bool IsModuleExport() const { return kind() == kModuleExport; }
100

101 102
  bool HasTransitionMap() const { return !transition_map().is_null(); }

103 104 105 106 107 108
  Kind kind() const { return kind_; }
  MaybeHandle<JSObject> holder() const { return holder_; }
  MaybeHandle<Map> transition_map() const { return transition_map_; }
  Handle<Object> constant() const { return constant_; }
  FieldIndex field_index() const { return field_index_; }
  Type* field_type() const { return field_type_; }
109 110 111
  MachineRepresentation field_representation() const {
    return field_representation_;
  }
112
  MaybeHandle<Map> field_map() const { return field_map_; }
113
  MapHandles const& receiver_maps() const { return receiver_maps_; }
114
  Handle<Cell> export_cell() const;
115 116

 private:
117
  PropertyAccessInfo(MaybeHandle<JSObject> holder,
118
                     MapHandles const& receiver_maps);
119
  PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
120
                     Handle<Object> constant, MapHandles const& receiver_maps);
121
  PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
122
                     MaybeHandle<Map> transition_map, FieldIndex field_index,
123
                     MachineRepresentation field_representation,
124
                     Type* field_type, MaybeHandle<Map> field_map,
125
                     MapHandles const& receiver_maps);
126 127

  Kind kind_;
128
  MapHandles receiver_maps_;
129 130 131 132
  Handle<Object> constant_;
  MaybeHandle<Map> transition_map_;
  MaybeHandle<JSObject> holder_;
  FieldIndex field_index_;
133
  MachineRepresentation field_representation_;
134
  Type* field_type_;
135
  MaybeHandle<Map> field_map_;
136 137 138
};


139 140
// Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
class AccessInfoFactory final {
141
 public:
142 143 144 145 146
  AccessInfoFactory(CompilationDependencies* dependencies,
                    Handle<Context> native_context, Zone* zone);

  bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
                                ElementAccessInfo* access_info);
147
  bool ComputeElementAccessInfos(MapHandles const& maps, AccessMode access_mode,
148
                                 ZoneVector<ElementAccessInfo>* access_infos);
149
  bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
150
                                 AccessMode access_mode,
151
                                 PropertyAccessInfo* access_info);
152
  bool ComputePropertyAccessInfos(MapHandles const& maps, Handle<Name> name,
153
                                  AccessMode access_mode,
154 155 156
                                  ZoneVector<PropertyAccessInfo>* access_infos);

 private:
157
  bool ConsolidateElementLoad(MapHandles const& maps,
158
                              ElementAccessInfo* access_info);
159 160 161 162 163 164
  bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
                                  PropertyAccessInfo* access_info);
  bool LookupTransition(Handle<Map> map, Handle<Name> name,
                        MaybeHandle<JSObject> holder,
                        PropertyAccessInfo* access_info);

165 166 167 168 169 170 171 172 173 174 175 176
  CompilationDependencies* dependencies() const { return dependencies_; }
  Factory* factory() const;
  Isolate* isolate() const { return isolate_; }
  Handle<Context> native_context() const { return native_context_; }
  Zone* zone() const { return zone_; }

  CompilationDependencies* const dependencies_;
  Handle<Context> const native_context_;
  Isolate* const isolate_;
  TypeCache const& type_cache_;
  Zone* const zone_;

177
  DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
178 179 180 181 182 183
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

184
#endif  // V8_COMPILER_ACCESS_INFO_H_