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 15namespace v8 { 16namespace internal { 17 18// Forward declarations. 19class CompilationDependencies; 20class Factory; 21 22namespace compiler { 23 24// Forward declarations. 25class Type; 26class 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. 30enum class AccessMode { kLoad, kStore, kStoreInLiteral }; 31 32std::ostream& operator<<(std::ostream&, AccessMode); 33 34typedef std::vector<Handle<Map>> MapList; 35 36// Mapping of transition source to transition target. 37typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList; 38 39// This class encapsulates all information required to access a certain element. 40class ElementAccessInfo final { 41 public: 42 ElementAccessInfo(); 43 ElementAccessInfo(MapList const& receiver_maps, ElementsKind elements_kind); 44 45 ElementsKind elements_kind() const { return elements_kind_; } 46 MapList const& receiver_maps() const { return receiver_maps_; } 47 MapTransitionList& transitions() { return 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. 58class 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 90 bool IsNotFound() const { return kind() == kNotFound; } 91 bool IsDataConstant() const { return kind() == kDataConstant; } 92 bool IsDataField() const { return kind() == kDataField; } 93 // TODO(ishell): rename to IsDataConstant() once constant field tracking 94 // is done. 95 bool IsDataConstantField() const { return kind() == kDataConstantField; } 96 bool IsAccessorConstant() const { return kind() == kAccessorConstant; } 97 bool IsGeneric() const { return kind() == kGeneric; } 98 99 bool HasTransitionMap() const { return !transition_map().is_null(); } 100 101 Kind kind() const { return kind_; } 102 MaybeHandle<JSObject> holder() const { return holder_; } 103 MaybeHandle<Map> transition_map() const { return transition_map_; } 104 Handle<Object> constant() const { return constant_; } 105 FieldIndex field_index() const { return field_index_; } 106 Type* field_type() const { return field_type_; } 107 MachineRepresentation field_representation() const { 108 return field_representation_; 109 } 110 MaybeHandle<Map> field_map() const { return field_map_; } 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. 137class 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 161 CompilationDependencies* dependencies() const { return dependencies_; } 162 Factory* factory() const; 163 Isolate* isolate() const { return isolate_; } 164 Handle<Context> native_context() const { return native_context_; } 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