Home | History | Annotate | Download | only in compiler
      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 
     45   ElementsKind elements_kind() const { return elements_kind_; }
     46   MapList const& receiver_maps() const { return receiver_maps_; }
     47   MapTransitionList& transitions() { return 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 
     90   bool IsNotFound() const { return kind() == kNotFound; }
     91   bool IsDataConstant() const { return kind() == kDataConstant; }
     92   bool IsDataField() const { return kind() == kDataField; }
     93   // TODO(ishell): rename to IsDataConstant() once constant field tracking
     94   // is done.
     95   bool IsDataConstantField() const { return kind() == kDataConstantField; }
     96   bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
     97   bool IsGeneric() const { return kind() == kGeneric; }
     98 
     99   bool HasTransitionMap() const { return !transition_map().is_null(); }
    100 
    101   Kind kind() const { return kind_; }
    102   MaybeHandle<JSObject> holder() const { return holder_; }
    103   MaybeHandle<Map> transition_map() const { return transition_map_; }
    104   Handle<Object> constant() const { return constant_; }
    105   FieldIndex field_index() const { return field_index_; }
    106   Type* field_type() const { return field_type_; }
    107   MachineRepresentation field_representation() const {
    108     return field_representation_;
    109   }
    110   MaybeHandle<Map> field_map() const { return field_map_; }
    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 
    161   CompilationDependencies* dependencies() const { return dependencies_; }
    162   Factory* factory() const;
    163   Isolate* isolate() const { return isolate_; }
    164   Handle<Context> native_context() const { return native_context_; }
    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