1 // Copyright 2014 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_TYPES_INL_H_ 6 #define V8_TYPES_INL_H_ 7 8 #include "src/types.h" 9 10 #include "src/factory.h" 11 #include "src/handles-inl.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // ----------------------------------------------------------------------------- 17 // TypeImpl 18 19 template<class Config> 20 TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) { 21 TypeImpl* t = static_cast<TypeImpl*>(object); 22 DCHECK(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() || 23 t->IsUnion() || t->IsArray() || t->IsFunction() || t->IsContext()); 24 return t; 25 } 26 27 28 // Most precise _current_ type of a value (usually its class). 29 template<class Config> 30 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf( 31 i::Object* value, Region* region) { 32 if (value->IsSmi() || 33 i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) { 34 return Of(value, region); 35 } 36 return Class(i::handle(i::HeapObject::cast(value)->map()), region); 37 } 38 39 40 template<class Config> 41 bool TypeImpl<Config>::NowContains(i::Object* value) { 42 DisallowHeapAllocation no_allocation; 43 if (this->IsAny()) return true; 44 if (value->IsHeapObject()) { 45 i::Map* map = i::HeapObject::cast(value)->map(); 46 for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) { 47 if (*it.Current() == map) return true; 48 } 49 } 50 return this->Contains(value); 51 } 52 53 54 // ----------------------------------------------------------------------------- 55 // ZoneTypeConfig 56 57 // static 58 template<class T> 59 T* ZoneTypeConfig::handle(T* type) { 60 return type; 61 } 62 63 64 // static 65 template<class T> 66 T* ZoneTypeConfig::cast(Type* type) { 67 return static_cast<T*>(type); 68 } 69 70 71 // static 72 bool ZoneTypeConfig::is_bitset(Type* type) { 73 return reinterpret_cast<uintptr_t>(type) & 1; 74 } 75 76 77 // static 78 bool ZoneTypeConfig::is_struct(Type* type, int tag) { 79 return !is_bitset(type) && struct_tag(as_struct(type)) == tag; 80 } 81 82 83 // static 84 bool ZoneTypeConfig::is_class(Type* type) { 85 return false; 86 } 87 88 89 // static 90 ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) { 91 DCHECK(is_bitset(type)); 92 return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u); 93 } 94 95 96 // static 97 ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) { 98 DCHECK(!is_bitset(type)); 99 return reinterpret_cast<Struct*>(type); 100 } 101 102 103 // static 104 i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) { 105 UNREACHABLE(); 106 return i::Handle<i::Map>(); 107 } 108 109 110 // static 111 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) { 112 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u)); 113 } 114 115 116 // static 117 ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset( 118 Type::bitset bitset, Zone* Zone) { 119 return from_bitset(bitset); 120 } 121 122 123 // static 124 ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) { 125 return reinterpret_cast<Type*>(structure); 126 } 127 128 129 // static 130 ZoneTypeConfig::Type* ZoneTypeConfig::from_class( 131 i::Handle<i::Map> map, Zone* zone) { 132 return from_bitset(0); 133 } 134 135 136 // static 137 ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create( 138 int tag, int length, Zone* zone) { 139 Struct* structure = reinterpret_cast<Struct*>( 140 zone->New(sizeof(void*) * (length + 2))); // NOLINT 141 structure[0] = reinterpret_cast<void*>(tag); 142 structure[1] = reinterpret_cast<void*>(length); 143 return structure; 144 } 145 146 147 // static 148 void ZoneTypeConfig::struct_shrink(Struct* structure, int length) { 149 DCHECK(0 <= length && length <= struct_length(structure)); 150 structure[1] = reinterpret_cast<void*>(length); 151 } 152 153 154 // static 155 int ZoneTypeConfig::struct_tag(Struct* structure) { 156 return static_cast<int>(reinterpret_cast<intptr_t>(structure[0])); 157 } 158 159 160 // static 161 int ZoneTypeConfig::struct_length(Struct* structure) { 162 return static_cast<int>(reinterpret_cast<intptr_t>(structure[1])); 163 } 164 165 166 // static 167 Type* ZoneTypeConfig::struct_get(Struct* structure, int i) { 168 DCHECK(0 <= i && i <= struct_length(structure)); 169 return static_cast<Type*>(structure[2 + i]); 170 } 171 172 173 // static 174 void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) { 175 DCHECK(0 <= i && i <= struct_length(structure)); 176 structure[2 + i] = x; 177 } 178 179 180 // static 181 template<class V> 182 i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) { 183 DCHECK(0 <= i && i <= struct_length(structure)); 184 return i::Handle<V>(static_cast<V**>(structure[2 + i])); 185 } 186 187 188 // static 189 template<class V> 190 void ZoneTypeConfig::struct_set_value( 191 Struct* structure, int i, i::Handle<V> x) { 192 DCHECK(0 <= i && i <= struct_length(structure)); 193 structure[2 + i] = x.location(); 194 } 195 196 197 // ----------------------------------------------------------------------------- 198 // HeapTypeConfig 199 200 // static 201 template<class T> 202 i::Handle<T> HeapTypeConfig::handle(T* type) { 203 return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); 204 } 205 206 207 // static 208 template<class T> 209 i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) { 210 return i::Handle<T>::cast(type); 211 } 212 213 214 // static 215 bool HeapTypeConfig::is_bitset(Type* type) { 216 return type->IsSmi(); 217 } 218 219 220 // static 221 bool HeapTypeConfig::is_class(Type* type) { 222 return type->IsMap(); 223 } 224 225 226 // static 227 bool HeapTypeConfig::is_struct(Type* type, int tag) { 228 return type->IsFixedArray() && struct_tag(as_struct(type)) == tag; 229 } 230 231 232 // static 233 HeapTypeConfig::Type::bitset HeapTypeConfig::as_bitset(Type* type) { 234 // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way. 235 return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type)); 236 } 237 238 239 // static 240 i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) { 241 return i::handle(i::Map::cast(type)); 242 } 243 244 245 // static 246 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) { 247 return i::handle(Struct::cast(type)); 248 } 249 250 251 // static 252 HeapTypeConfig::Type* HeapTypeConfig::from_bitset(Type::bitset bitset) { 253 // TODO(rossberg): Breaks the Smi abstraction. Fix once there is a better way. 254 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset)); 255 } 256 257 258 // static 259 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset( 260 Type::bitset bitset, Isolate* isolate) { 261 return i::handle(from_bitset(bitset), isolate); 262 } 263 264 265 // static 266 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class( 267 i::Handle<i::Map> map, Isolate* isolate) { 268 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); 269 } 270 271 272 // static 273 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct( 274 i::Handle<Struct> structure) { 275 return i::Handle<Type>::cast(i::Handle<Object>::cast(structure)); 276 } 277 278 279 // static 280 i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create( 281 int tag, int length, Isolate* isolate) { 282 i::Handle<Struct> structure = isolate->factory()->NewFixedArray(length + 1); 283 structure->set(0, i::Smi::FromInt(tag)); 284 return structure; 285 } 286 287 288 // static 289 void HeapTypeConfig::struct_shrink(i::Handle<Struct> structure, int length) { 290 structure->Shrink(length + 1); 291 } 292 293 294 // static 295 int HeapTypeConfig::struct_tag(i::Handle<Struct> structure) { 296 return static_cast<i::Smi*>(structure->get(0))->value(); 297 } 298 299 300 // static 301 int HeapTypeConfig::struct_length(i::Handle<Struct> structure) { 302 return structure->length() - 1; 303 } 304 305 306 // static 307 i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get( 308 i::Handle<Struct> structure, int i) { 309 Type* type = static_cast<Type*>(structure->get(i + 1)); 310 return i::handle(type, structure->GetIsolate()); 311 } 312 313 314 // static 315 void HeapTypeConfig::struct_set( 316 i::Handle<Struct> structure, int i, i::Handle<Type> type) { 317 structure->set(i + 1, *type); 318 } 319 320 321 // static 322 template<class V> 323 i::Handle<V> HeapTypeConfig::struct_get_value( 324 i::Handle<Struct> structure, int i) { 325 V* x = static_cast<V*>(structure->get(i + 1)); 326 return i::handle(x, structure->GetIsolate()); 327 } 328 329 330 // static 331 template<class V> 332 void HeapTypeConfig::struct_set_value( 333 i::Handle<Struct> structure, int i, i::Handle<V> x) { 334 structure->set(i + 1, *x); 335 } 336 337 } } // namespace v8::internal 338 339 #endif // V8_TYPES_INL_H_ 340