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/compiler/types.h"
     11 #include "src/field-index.h"
     12 #include "src/machine-type.h"
     13 #include "src/objects.h"
     14 #include "src/objects/map.h"
     15 #include "src/zone/zone-containers.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 
     20 // Forward declarations.
     21 class Factory;
     22 
     23 namespace compiler {
     24 
     25 // Forward declarations.
     26 class CompilationDependencies;
     27 class Type;
     28 class TypeCache;
     29 
     30 // Whether we are loading a property or storing to a property.
     31 // For a store during literal creation, do not walk up the prototype chain.
     32 enum class AccessMode { kLoad, kStore, kStoreInLiteral };
     33 
     34 std::ostream& operator<<(std::ostream&, AccessMode);
     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(MapHandles const& receiver_maps,
     44                     ElementsKind elements_kind);
     45 
     46   ElementsKind elements_kind() const { return elements_kind_; }
     47   MapHandles const& receiver_maps() const { return receiver_maps_; }
     48   MapTransitionList& transitions() { return transitions_; }
     49   MapTransitionList const& transitions() const { return transitions_; }
     50 
     51  private:
     52   ElementsKind elements_kind_;
     53   MapHandles receiver_maps_;
     54   MapTransitionList transitions_;
     55 };
     56 
     57 // This class encapsulates all information required to access a certain
     58 // object property, either on the object itself or on the prototype chain.
     59 class PropertyAccessInfo final {
     60  public:
     61   enum Kind {
     62     kInvalid,
     63     kNotFound,
     64     kDataConstant,
     65     kDataField,
     66     kDataConstantField,
     67     kAccessorConstant,
     68     kModuleExport
     69   };
     70 
     71   static PropertyAccessInfo NotFound(MapHandles const& receiver_maps,
     72                                      MaybeHandle<JSObject> holder);
     73   static PropertyAccessInfo DataConstant(MapHandles const& receiver_maps,
     74                                          Handle<Object> constant,
     75                                          MaybeHandle<JSObject> holder);
     76   static PropertyAccessInfo DataField(
     77       PropertyConstness constness, MapHandles const& receiver_maps,
     78       FieldIndex field_index, MachineRepresentation field_representation,
     79       Type field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(),
     80       MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
     81       MaybeHandle<Map> transition_map = MaybeHandle<Map>());
     82   static PropertyAccessInfo AccessorConstant(MapHandles const& receiver_maps,
     83                                              Handle<Object> constant,
     84                                              MaybeHandle<JSObject> holder);
     85   static PropertyAccessInfo ModuleExport(MapHandles const& receiver_maps,
     86                                          Handle<Cell> cell);
     87 
     88   PropertyAccessInfo();
     89 
     90   bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
     91              Zone* zone) V8_WARN_UNUSED_RESULT;
     92 
     93   bool IsNotFound() const { return kind() == kNotFound; }
     94   bool IsDataConstant() const { return kind() == kDataConstant; }
     95   bool IsDataField() const { return kind() == kDataField; }
     96   // TODO(ishell): rename to IsDataConstant() once constant field tracking
     97   // is done.
     98   bool IsDataConstantField() const { return kind() == kDataConstantField; }
     99   bool IsAccessorConstant() const { return kind() == kAccessorConstant; }
    100   bool IsModuleExport() const { return kind() == kModuleExport; }
    101 
    102   bool HasTransitionMap() const { return !transition_map().is_null(); }
    103 
    104   Kind kind() const { return kind_; }
    105   MaybeHandle<JSObject> holder() const { return holder_; }
    106   MaybeHandle<Map> transition_map() const { return transition_map_; }
    107   Handle<Object> constant() const { return constant_; }
    108   FieldIndex field_index() const { return field_index_; }
    109   Type field_type() const { return field_type_; }
    110   MachineRepresentation field_representation() const {
    111     return field_representation_;
    112   }
    113   MaybeHandle<Map> field_map() const { return field_map_; }
    114   MapHandles const& receiver_maps() const { return receiver_maps_; }
    115   Handle<Cell> export_cell() const;
    116 
    117  private:
    118   PropertyAccessInfo(MaybeHandle<JSObject> holder,
    119                      MapHandles const& receiver_maps);
    120   PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
    121                      Handle<Object> constant, MapHandles const& receiver_maps);
    122   PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
    123                      MaybeHandle<Map> transition_map, FieldIndex field_index,
    124                      MachineRepresentation field_representation,
    125                      Type field_type, MaybeHandle<Map> field_map,
    126                      MapHandles const& receiver_maps);
    127 
    128   Kind kind_;
    129   MapHandles receiver_maps_;
    130   Handle<Object> constant_;
    131   MaybeHandle<Map> transition_map_;
    132   MaybeHandle<JSObject> holder_;
    133   FieldIndex field_index_;
    134   MachineRepresentation field_representation_;
    135   Type field_type_;
    136   MaybeHandle<Map> field_map_;
    137 };
    138 
    139 
    140 // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
    141 class AccessInfoFactory final {
    142  public:
    143   AccessInfoFactory(JSHeapBroker* js_heap_broker,
    144                     CompilationDependencies* dependencies,
    145 
    146                     Handle<Context> native_context, Zone* zone);
    147 
    148   bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
    149                                 ElementAccessInfo* access_info);
    150   bool ComputeElementAccessInfos(MapHandles const& maps, AccessMode access_mode,
    151                                  ZoneVector<ElementAccessInfo>* access_infos);
    152   bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
    153                                  AccessMode access_mode,
    154                                  PropertyAccessInfo* access_info);
    155   bool ComputePropertyAccessInfo(MapHandles const& maps, Handle<Name> name,
    156                                  AccessMode access_mode,
    157                                  PropertyAccessInfo* access_info);
    158   bool ComputePropertyAccessInfos(MapHandles const& maps, Handle<Name> name,
    159                                   AccessMode access_mode,
    160                                   ZoneVector<PropertyAccessInfo>* access_infos);
    161 
    162  private:
    163   bool ConsolidateElementLoad(MapHandles const& maps,
    164                               ElementAccessInfo* access_info);
    165   bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
    166                                   PropertyAccessInfo* access_info);
    167   bool LookupTransition(Handle<Map> map, Handle<Name> name,
    168                         MaybeHandle<JSObject> holder,
    169                         PropertyAccessInfo* access_info);
    170 
    171   CompilationDependencies* dependencies() const { return dependencies_; }
    172   JSHeapBroker* js_heap_broker() const { return js_heap_broker_; }
    173   Factory* factory() const;
    174   Isolate* isolate() const { return isolate_; }
    175   Handle<Context> native_context() const { return native_context_; }
    176   Zone* zone() const { return zone_; }
    177 
    178   JSHeapBroker* const js_heap_broker_;
    179   CompilationDependencies* const dependencies_;
    180   Handle<Context> const native_context_;
    181   Isolate* const isolate_;
    182   TypeCache const& type_cache_;
    183   Zone* const zone_;
    184 
    185   DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
    186 };
    187 
    188 }  // namespace compiler
    189 }  // namespace internal
    190 }  // namespace v8
    191 
    192 #endif  // V8_COMPILER_ACCESS_INFO_H_
    193