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