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 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 
     44   ElementsKind elements_kind() const { return elements_kind_; }
     45   MapList const& receiver_maps() const { return receiver_maps_; }
     46   MapTransitionList& transitions() { return 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 
     88   bool IsNotFound() const { return kind() == kNotFound; }
     89   bool IsDataConstant() const { return kind() == kDataConstant; }
     90   bool IsDataField() const { return kind() == kDataField; }
     91   bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
     92   bool IsGeneric() const { return kind() == kGeneric; }
     93 
     94   bool HasTransitionMap() const { return !transition_map().is_null(); }
     95 
     96   Kind kind() const { return kind_; }
     97   MaybeHandle<JSObject> holder() const { return holder_; }
     98   MaybeHandle<Map> transition_map() const { return transition_map_; }
     99   Handle<Object> constant() const { return constant_; }
    100   FieldIndex field_index() const { return field_index_; }
    101   Type* field_type() const { return field_type_; }
    102   MachineRepresentation field_representation() const {
    103     return field_representation_;
    104   }
    105   MaybeHandle<Map> field_map() const { return field_map_; }
    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 
    156   CompilationDependencies* dependencies() const { return dependencies_; }
    157   Factory* factory() const;
    158   Isolate* isolate() const { return isolate_; }
    159   Handle<Context> native_context() const { return native_context_; }
    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