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 // For a store during literal creation, do not walk up the prototype chain. 30 enum class AccessMode { kLoad, kStore, kStoreInLiteral }; 31 32 std::ostream& operator<<(std::ostream&, AccessMode); 33 34 typedef std::vector<Handle<Map>> MapList; 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(MapList const& receiver_maps, ElementsKind elements_kind); 44 elements_kind()45 ElementsKind elements_kind() const { return elements_kind_; } receiver_maps()46 MapList const& receiver_maps() const { return receiver_maps_; } transitions()47 MapTransitionList& transitions() { return transitions_; } transitions()48 MapTransitionList const& transitions() const { return transitions_; } 49 50 private: 51 ElementsKind elements_kind_; 52 MapList receiver_maps_; 53 MapTransitionList transitions_; 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 { 61 kInvalid, 62 kNotFound, 63 kDataConstant, 64 kDataField, 65 kDataConstantField, 66 kAccessorConstant, 67 kGeneric 68 }; 69 70 static PropertyAccessInfo NotFound(MapList const& receiver_maps, 71 MaybeHandle<JSObject> holder); 72 static PropertyAccessInfo DataConstant(MapList const& receiver_maps, 73 Handle<Object> constant, 74 MaybeHandle<JSObject> holder); 75 static PropertyAccessInfo DataField( 76 PropertyConstness constness, MapList const& receiver_maps, 77 FieldIndex field_index, MachineRepresentation field_representation, 78 Type* field_type, MaybeHandle<Map> field_map = MaybeHandle<Map>(), 79 MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(), 80 MaybeHandle<Map> transition_map = MaybeHandle<Map>()); 81 static PropertyAccessInfo AccessorConstant(MapList const& receiver_maps, 82 Handle<Object> constant, 83 MaybeHandle<JSObject> holder); 84 static PropertyAccessInfo Generic(MapList const& receiver_maps); 85 86 PropertyAccessInfo(); 87 88 bool Merge(PropertyAccessInfo const* that) WARN_UNUSED_RESULT; 89 IsNotFound()90 bool IsNotFound() const { return kind() == kNotFound; } IsDataConstant()91 bool IsDataConstant() const { return kind() == kDataConstant; } IsDataField()92 bool IsDataField() const { return kind() == kDataField; } 93 // TODO(ishell): rename to IsDataConstant() once constant field tracking 94 // is done. IsDataConstantField()95 bool IsDataConstantField() const { return kind() == kDataConstantField; } IsAccessorConstant()96 bool IsAccessorConstant() const { return kind() == kAccessorConstant; } IsGeneric()97 bool IsGeneric() const { return kind() == kGeneric; } 98 HasTransitionMap()99 bool HasTransitionMap() const { return !transition_map().is_null(); } 100 kind()101 Kind kind() const { return kind_; } holder()102 MaybeHandle<JSObject> holder() const { return holder_; } transition_map()103 MaybeHandle<Map> transition_map() const { return transition_map_; } constant()104 Handle<Object> constant() const { return constant_; } field_index()105 FieldIndex field_index() const { return field_index_; } field_type()106 Type* field_type() const { return field_type_; } field_representation()107 MachineRepresentation field_representation() const { 108 return field_representation_; 109 } field_map()110 MaybeHandle<Map> field_map() const { return field_map_; } receiver_maps()111 MapList const& receiver_maps() const { return receiver_maps_; } 112 113 private: 114 PropertyAccessInfo(MaybeHandle<JSObject> holder, 115 MapList const& receiver_maps); 116 PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, 117 Handle<Object> constant, MapList const& receiver_maps); 118 PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, 119 MaybeHandle<Map> transition_map, FieldIndex field_index, 120 MachineRepresentation field_representation, 121 Type* field_type, MaybeHandle<Map> field_map, 122 MapList const& receiver_maps); 123 124 Kind kind_; 125 MapList receiver_maps_; 126 Handle<Object> constant_; 127 MaybeHandle<Map> transition_map_; 128 MaybeHandle<JSObject> holder_; 129 FieldIndex field_index_; 130 MachineRepresentation field_representation_; 131 Type* field_type_; 132 MaybeHandle<Map> field_map_; 133 }; 134 135 136 // Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s. 137 class AccessInfoFactory final { 138 public: 139 AccessInfoFactory(CompilationDependencies* dependencies, 140 Handle<Context> native_context, Zone* zone); 141 142 bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode, 143 ElementAccessInfo* access_info); 144 bool ComputeElementAccessInfos(MapHandleList const& maps, 145 AccessMode access_mode, 146 ZoneVector<ElementAccessInfo>* access_infos); 147 bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name, 148 AccessMode access_mode, 149 PropertyAccessInfo* access_info); 150 bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name, 151 AccessMode access_mode, 152 ZoneVector<PropertyAccessInfo>* access_infos); 153 154 private: 155 bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name, 156 PropertyAccessInfo* access_info); 157 bool LookupTransition(Handle<Map> map, Handle<Name> name, 158 MaybeHandle<JSObject> holder, 159 PropertyAccessInfo* access_info); 160 dependencies()161 CompilationDependencies* dependencies() const { return dependencies_; } 162 Factory* factory() const; isolate()163 Isolate* isolate() const { return isolate_; } native_context()164 Handle<Context> native_context() const { return native_context_; } zone()165 Zone* zone() const { return zone_; } 166 167 CompilationDependencies* const dependencies_; 168 Handle<Context> const native_context_; 169 Isolate* const isolate_; 170 TypeCache const& type_cache_; 171 Zone* const zone_; 172 173 DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory); 174 }; 175 176 } // namespace compiler 177 } // namespace internal 178 } // namespace v8 179 180 #endif // V8_COMPILER_ACCESS_INFO_H_ 181