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 elements_kind()46 ElementsKind elements_kind() const { return elements_kind_; } receiver_maps()47 MapHandles const& receiver_maps() const { return receiver_maps_; } transitions()48 MapTransitionList& transitions() { return transitions_; } 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 IsNotFound()93 bool IsNotFound() const { return kind() == kNotFound; } IsDataConstant()94 bool IsDataConstant() const { return kind() == kDataConstant; } IsDataField()95 bool IsDataField() const { return kind() == kDataField; } 96 // TODO(ishell): rename to IsDataConstant() once constant field tracking 97 // is done. IsDataConstantField()98 bool IsDataConstantField() const { return kind() == kDataConstantField; } IsAccessorConstant()99 bool IsAccessorConstant() const { return kind() == kAccessorConstant; } IsModuleExport()100 bool IsModuleExport() const { return kind() == kModuleExport; } 101 HasTransitionMap()102 bool HasTransitionMap() const { return !transition_map().is_null(); } 103 kind()104 Kind kind() const { return kind_; } holder()105 MaybeHandle<JSObject> holder() const { return holder_; } transition_map()106 MaybeHandle<Map> transition_map() const { return transition_map_; } constant()107 Handle<Object> constant() const { return constant_; } field_index()108 FieldIndex field_index() const { return field_index_; } field_type()109 Type field_type() const { return field_type_; } field_representation()110 MachineRepresentation field_representation() const { 111 return field_representation_; 112 } field_map()113 MaybeHandle<Map> field_map() const { return field_map_; } receiver_maps()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 dependencies()171 CompilationDependencies* dependencies() const { return dependencies_; } js_heap_broker()172 JSHeapBroker* js_heap_broker() const { return js_heap_broker_; } 173 Factory* factory() const; isolate()174 Isolate* isolate() const { return isolate_; } native_context()175 Handle<Context> native_context() const { return native_context_; } zone()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