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 // Additional checks that need to be perform for data field accesses.
     57 enum class FieldCheck : uint8_t {
     58   // No additional checking needed.
     59   kNone,
     60   // Check that the [[ViewedArrayBuffer]] of {JSArrayBufferView}s
     61   // was not neutered.
     62   kJSArrayBufferViewBufferNotNeutered,
     63 };
     64 
     65 
     66 // This class encapsulates all information required to access a certain
     67 // object property, either on the object itself or on the prototype chain.
     68 class PropertyAccessInfo final {
     69  public:
     70   enum Kind { kInvalid, kNotFound, kDataConstant, kDataField };
     71 
     72   static PropertyAccessInfo NotFound(Type* receiver_type,
     73                                      MaybeHandle<JSObject> holder);
     74   static PropertyAccessInfo DataConstant(Type* receiver_type,
     75                                          Handle<Object> constant,
     76                                          MaybeHandle<JSObject> holder);
     77   static PropertyAccessInfo DataField(
     78       Type* receiver_type, FieldIndex field_index, Type* field_type,
     79       FieldCheck field_check = FieldCheck::kNone,
     80       MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
     81       MaybeHandle<Map> transition_map = MaybeHandle<Map>());
     82 
     83   PropertyAccessInfo();
     84 
     85   bool IsNotFound() const { return kind() == kNotFound; }
     86   bool IsDataConstant() const { return kind() == kDataConstant; }
     87   bool IsDataField() const { return kind() == kDataField; }
     88 
     89   bool HasTransitionMap() const { return !transition_map().is_null(); }
     90 
     91   Kind kind() const { return kind_; }
     92   MaybeHandle<JSObject> holder() const { return holder_; }
     93   MaybeHandle<Map> transition_map() const { return transition_map_; }
     94   Handle<Object> constant() const { return constant_; }
     95   FieldCheck field_check() const { return field_check_; }
     96   FieldIndex field_index() const { return field_index_; }
     97   Type* field_type() const { return field_type_; }
     98   Type* receiver_type() const { return receiver_type_; }
     99 
    100  private:
    101   PropertyAccessInfo(MaybeHandle<JSObject> holder, Type* receiver_type);
    102   PropertyAccessInfo(MaybeHandle<JSObject> holder, Handle<Object> constant,
    103                      Type* receiver_type);
    104   PropertyAccessInfo(MaybeHandle<JSObject> holder,
    105                      MaybeHandle<Map> transition_map, FieldIndex field_index,
    106                      FieldCheck field_check, Type* field_type,
    107                      Type* receiver_type);
    108 
    109   Kind kind_;
    110   Type* receiver_type_;
    111   Handle<Object> constant_;
    112   MaybeHandle<Map> transition_map_;
    113   MaybeHandle<JSObject> holder_;
    114   FieldIndex field_index_;
    115   FieldCheck field_check_;
    116   Type* field_type_;
    117 };
    118 
    119 
    120 // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
    121 class AccessInfoFactory final {
    122  public:
    123   AccessInfoFactory(CompilationDependencies* dependencies,
    124                     Handle<Context> native_context, Zone* zone);
    125 
    126   bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
    127                                 ElementAccessInfo* access_info);
    128   bool ComputeElementAccessInfos(MapHandleList const& maps,
    129                                  AccessMode access_mode,
    130                                  ZoneVector<ElementAccessInfo>* access_infos);
    131   bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
    132                                  AccessMode access_mode,
    133                                  PropertyAccessInfo* access_info);
    134   bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
    135                                   AccessMode access_mode,
    136                                   ZoneVector<PropertyAccessInfo>* access_infos);
    137 
    138  private:
    139   bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
    140                                   PropertyAccessInfo* access_info);
    141   bool LookupTransition(Handle<Map> map, Handle<Name> name,
    142                         MaybeHandle<JSObject> holder,
    143                         PropertyAccessInfo* access_info);
    144 
    145   CompilationDependencies* dependencies() const { return dependencies_; }
    146   Factory* factory() const;
    147   Isolate* isolate() const { return isolate_; }
    148   Handle<Context> native_context() const { return native_context_; }
    149   Zone* zone() const { return zone_; }
    150 
    151   CompilationDependencies* const dependencies_;
    152   Handle<Context> const native_context_;
    153   Isolate* const isolate_;
    154   TypeCache const& type_cache_;
    155   Zone* const zone_;
    156 
    157   DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
    158 };
    159 
    160 }  // namespace compiler
    161 }  // namespace internal
    162 }  // namespace v8
    163 
    164 #endif  // V8_COMPILER_ACCESS_INFO_H_
    165