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/objects.h"
     12 #include "src/zone-containers.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 // Forward declarations.
     18 class CompilationDependencies;
     19 class Factory;
     20 class TypeCache;
     21 
     22 
     23 namespace compiler {
     24 
     25 // Whether we are loading a property or storing to a property.
     26 enum class AccessMode { kLoad, kStore };
     27 
     28 std::ostream& operator<<(std::ostream&, AccessMode);
     29 
     30 
     31 // Mapping of transition source to transition target.
     32 typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
     33 
     34 
     35 // This class encapsulates all information required to access a certain element.
     36 class 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.
     58 class 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.
    107 class 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